Java方法区的理解

时间:2021-02-28 10:52:50   收藏:0   阅读:147

基本理解


方法区大小设置


方法区内部结构

方法区存储什么?

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

类型信息

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

  1. 这个类型的完整有效名称(全名=包名.类名)
  2. 这个类型直接父类的完整有效名
  3. 这个类型的修饰符(public , abstract , final的某个子集)
  4. 这个类型直接接口的一个有序列表

域(Field)信息

方法(Method)信息

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

non-final的类变量

全局常量:static final

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

常量池与运行时常量池

常量池:

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

运行时常量池:

方法区在jdk678的演变过程

jdk6:

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

技术分享图片

jdk7:

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

技术分享图片

jdk8:

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

技术分享图片

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

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

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

  2. 对永久代进行调优很困难

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

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

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

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

评论(0
© 2014 bubuko.com 版权所有 - 联系我们:wmxa8@hotmail.com
打开技术之扣,分享程序人生!