热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

java方法区释放_Java方法区的理解

方法区逻辑上是属于堆的一部分,但一些简单的实现可能不会选择去进行垃圾收集或者进行压缩。但对于HotSpotJVM而言,方法区还有一个别名叫做Non-He

方法区逻辑上是属于堆的一部分,但一些简单的实现可能不会选择去进行垃圾收集或者进行压缩。

但对于HotSpotJVM而言,方法区还有一个别名叫做Non-Heap,目的就是要和堆分开

所以方法区看作是一块独立于Java堆的内存空间

基本理解

方法区(Method Area) 与Java堆一样,是各个线程共享的内存区域.

方法区在JVM启动的时候被创建,并且它的实际的物理内存空间中和Java堆区一样都可以是不连续的.

方法区的大小,跟堆空间一样,可以选择固定大小或者可拓展.

方法区的大小决定了系统可以保存多少个类,如果系统定义了太多的类,导致方法区溢出,虚拟机同样会抛出内存溢出错误:java.lang.OutOfMemoryError: PermGen space(1.8以前)或者java.lang.OutOfMemoryError: Metaspace(1.8及以后)

加载大量的第三方的Jar包;Tomcat部署的工程过多(30-50个);大量动态的生成反射类

关闭JVM就会释放这个区域的内存

方法区大小设置

1.8及以后

设置初始值-XX:MetaspaceSize=100m

设置最大值-XX:MaxMetaspaceSize=100m(默认值是-1,表示没有限制)

方法区内部结构

方法区存储什么?

方法区 它用于存储已被虚拟机加载的类型信息,常量,静态变量,即时编译器编译后的代码缓存等

类型信息

对每个加载的类型(class,interface,enum,annotation),JVM必须在方法区中存储以下类型信息:

这个类型的完整有效名称(全名=包名.类名)

这个类型直接父类的完整有效名

这个类型的修饰符(public , abstract , final的某个子集)

这个类型直接接口的一个有序列表

域(Field)信息

JVM必须在方法区中保存类型的所有域的相关信息以及域的声明顺序

域的相关信息包括:域名称,域类型,域修饰符

方法(Method)信息

JVM必须保存所有方法的以下信息,同域信息一样包括声明顺序

方法名称

方法的返回类型

方法参数的数量和类型

方法的修饰符

方法的字节码,操作数栈,局部变量表及大小(abstract和native方法除外)

异常表

每个异常处理的开始位置,结束位置,代码处理在程序计数器中的偏移地址,被捕获的异常类的常量池索引

non-final的类变量

静态变量和类关联在一起,随着类的加载而加载,他们成为类数据在逻辑上的一部分

类变量被类的所有实例共享,即使没有类实例时你也可以访问它

全局常量:static final

被声明为final的类变量的处理方法则不同,每个全局常量在编译的时候就会被分配

常量池与运行时常量池

常量池:

一个有效的字节码文件中除了包含类的版本信息,字段,方法以及接口等描述信息外,还包含一项信息那就是常量池表,包括各种字面量和对类型,域和方法的符号引用

简单来说,常量池可以看作是一张表,虚拟机指令根据这张常量表找到要执行的类名,方法名,参数类型,字面量等类型

运行时常量池:

运行时常量池是方法区的一部分

常量池表是class文件的一部分,用于存放编译期生成的各种字面量与符号引用,这部分内容将在类加载后放到方法区的运行时常量池中.

在加载类和接口到虚拟机后,就会创建对应的运行时常量池

JVM为每个已加载的类型都维护一个常量池.池中的数据像数组项一样,是通过索引访问

运行时常量池相对于Class文件常量池的另一重要特征是:具备动态性

方法区在jdk678的演变过程

jdk6:

方法区是个概念,具体实现是通过永久代来实现

626d0e2134ad5a7eaddbc2ed9ed58be9.png

jdk7:

将静态变量和StringTable放到了堆空间中

1e03523c1ddab84c9a5354332ca40958.png

jdk8:

方法区的实现由元空间实现,存储在本地内存上,不在占用虚拟机内存.

8a7eb25c60f82c339865768617c1c730.png

为什么要用元空间替换永久代?

为永久代设置空间大小很难确定

在某些场景下,如果动态加载类过多,容易产生Perm区的OOM.比如某个实际Web工程中,因为功能点比较多,在运行过程中,要不断动态加载很多类,经常出现致命错误

对永久代进行调优很困难

为什么要将StringTable调整到堆空间中?

jdk7中将StringTable放到了堆空间中,因为永久代的回收效率很低,在full gc的时候才会触发.而full gc是老年代的空间不足,永久代不足时才会触发.

这就导致了StringTable回收效率不高.而我们开发中会有大量的字符串被创建,回收效率低,导致永久代内存不足,放到堆里,能及时回收内存

原文:https://www.cnblogs.com/LongDa666/p/14457945.html



推荐阅读
  • 深入探索HTTP协议的学习与实践
    在初次访问某个网站时,由于本地没有缓存,服务器会返回一个200状态码的响应,并在响应头中设置Etag和Last-Modified等缓存控制字段。这些字段用于后续请求时验证资源是否已更新,从而提高页面加载速度和减少带宽消耗。本文将深入探讨HTTP缓存机制及其在实际应用中的优化策略,帮助读者更好地理解和运用HTTP协议。 ... [详细]
  • 本文深入解析了JDK 8中HashMap的源代码,重点探讨了put方法的工作机制及其内部参数的设定原理。HashMap允许键和值为null,但键为null的情况只能出现一次,因为null键在内部通过索引0进行存储。文章详细分析了capacity(容量)、size(大小)、loadFactor(加载因子)以及红黑树转换阈值的设定原则,帮助读者更好地理解HashMap的高效实现和性能优化策略。 ... [详细]
  • Netty框架中运用Protobuf实现高效通信协议
    在Netty框架中,通过引入Protobuf来实现高效的通信协议。为了使用Protobuf,需要先准备好环境,包括下载并安装Protobuf的代码生成器`protoc`以及相应的源码包。具体资源可从官方下载页面获取,确保版本兼容性以充分发挥其性能优势。此外,配置好开发环境后,可以通过定义`.proto`文件来自动生成Java类,从而简化数据序列化和反序列化的操作,提高通信效率。 ... [详细]
  • 在处理遗留数据库的映射时,反向工程是一个重要的初始步骤。由于实体模式已经在数据库系统中存在,Hibernate 提供了自动化工具来简化这一过程,帮助开发人员快速生成持久化类和映射文件。通过反向工程,可以显著提高开发效率并减少手动配置的错误。此外,该工具还支持对现有数据库结构进行分析,自动生成符合 Hibernate 规范的配置文件,从而加速项目的启动和开发周期。 ... [详细]
  • 基址获取与驱动开发:内核中提取ntoskrnl模块的基地址方法解析
    基址获取与驱动开发:内核中提取ntoskrnl模块的基地址方法解析 ... [详细]
  • Ihavetwomethodsofgeneratingmdistinctrandomnumbersintherange[0..n-1]我有两种方法在范围[0.n-1]中生 ... [详细]
  • 本文详细介绍了 PHP 中对象的生命周期、内存管理和魔术方法的使用,包括对象的自动销毁、析构函数的作用以及各种魔术方法的具体应用场景。 ... [详细]
  • 本文介绍了一种在ANSI C中动态分配二维数组的方法。通过创建指针数组并为每个指针分配连续空间,可以灵活地管理内存。文章还讨论了一些常见的错误和注意事项。 ... [详细]
  • Flutter中计算文本尺寸的方法
    在Flutter开发中,有时需要计算文本的宽度和高度。本文介绍了一种利用TextPainter类实现这一功能的方法。 ... [详细]
  • 本文详细解析了客户端与服务器之间的交互过程,重点介绍了Socket通信机制。IP地址由32位的4个8位二进制数组成,分为网络地址和主机地址两部分。通过使用 `ipconfig /all` 命令,用户可以查看详细的IP配置信息。此外,文章还介绍了如何使用 `ping` 命令测试网络连通性,例如 `ping 127.0.0.1` 可以检测本机网络是否正常。这些技术细节对于理解网络通信的基本原理具有重要意义。 ... [详细]
  • 在《Cocos2d-x学习笔记:基础概念解析与内存管理机制深入探讨》中,详细介绍了Cocos2d-x的基础概念,并深入分析了其内存管理机制。特别是针对Boost库引入的智能指针管理方法进行了详细的讲解,例如在处理鱼的运动过程中,可以通过编写自定义函数来动态计算角度变化,利用CallFunc回调机制实现高效的游戏逻辑控制。此外,文章还探讨了如何通过智能指针优化资源管理和避免内存泄漏,为开发者提供了实用的编程技巧和最佳实践。 ... [详细]
  • Java Socket 关键参数详解与优化建议
    Java Socket 的 API 虽然被广泛使用,但其关键参数的用途却鲜为人知。本文详细解析了 Java Socket 中的重要参数,如 backlog 参数,它用于控制服务器等待连接请求的队列长度。此外,还探讨了其他参数如 SO_TIMEOUT、SO_REUSEADDR 等的配置方法及其对性能的影响,并提供了优化建议,帮助开发者提升网络通信的稳定性和效率。 ... [详细]
  • 使用Maven JAR插件将单个或多个文件及其依赖项合并为一个可引用的JAR包
    本文介绍了如何利用Maven中的maven-assembly-plugin插件将单个或多个Java文件及其依赖项打包成一个可引用的JAR文件。首先,需要创建一个新的Maven项目,并将待打包的Java文件复制到该项目中。通过配置maven-assembly-plugin,可以实现将所有文件及其依赖项合并为一个独立的JAR包,方便在其他项目中引用和使用。此外,该方法还支持自定义装配描述符,以满足不同场景下的需求。 ... [详细]
  • 在Java Web服务开发中,Apache CXF 和 Axis2 是两个广泛使用的框架。CXF 由于其与 Spring 框架的无缝集成能力,以及更简便的部署方式,成为了许多开发者的首选。本文将详细介绍如何使用 CXF 框架进行 Web 服务的开发,包括环境搭建、服务发布和客户端调用等关键步骤,为开发者提供一个全面的实践指南。 ... [详细]
  • Spring框架的核心组件与架构解析 ... [详细]
author-avatar
很呆很傻很天真2010_545
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有