JVM——方法区

JVM——方法区

在这里插入图片描述
栈、堆、方法区的关系
在这里插入图片描述
方法区和堆一样是每一个线程共享的
方法区异常:

方法区的大小决定了系统可以保存多少个类,如果系统定义了太多的类,导致方法区溢出,虚拟机同样会抛出内存溢出错误: java.lang.outOfMemoryError:
PermGen space或者java.lang.outOfMemoryError: Metaspace
·加载大量的第三方的jar包;Tomcat部署的工程过多(30-50个)大量动态的
生成反射类

在这里插入图片描述

设置方法区大小与OOM

jdk7及以前:
-XX : PermSize来设置永久代初始分配空间。默认值是20.75M
-XX:MaxPermSize来设定永久代最大可分配空间。32位机器默认是64M,64位机器模式是82M

jdk8及以后:
元数据区大小可以使用参数-XX:MetaspaceSize和-XX:MaxMetaspaceSize指定,替代上述原有的两个参数。
默认值依赖于平台。windows下,-XX:Metaspacesize是21M,-XX:MaxMetaspacesize
的值是-1,即没有限制。

在这里插入图片描述

方法区的内部结构:

在这里插入图片描述

类型信息:

①对每个加载的类型(类class、接口interface、枚举enum、注解annotation) ,JVM必须在方法区中存储以下类型信息:
②这个类型的完整有效名称(全名=包名.类名)
③这个类型直接父类的完整有效名(对于interface或是java.lang.0bject,都没有父类)
④这个类型的修饰符(public,abstract,final的某个子集) ④这个类型直接接口的一个有序列表

在这里插入图片描述
在这里插入图片描述
补充说明:全局常量: static final
被声明为final的类变量的处理方法则不同,每个全局常量在编译的时候就会被分配了。I

运行时常量池 vs 常量池

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

为什么需要常量池?

我们在编译一个java文件生成字节码文件后,这个字节码文件代码量可能很小,那么因为
要引用一些别的类结构,比如说写一个字符串我们要用到String类,创建对象也要用到Object的构造器,这些引用加起来我们数据量就会非常大了,所有我们使用常量池来解决这一问题。
在这里插入图片描述
小结:
其实我们可以把常量池看作一张表,虚拟机通过对应的符号引用找到常量表中的,字面量、类名、方法名。

运行时常量池:
指class文件通过类加载器,加载到我们方法区中的运行时常量池。

运行时常量池中包含多种不同的常量,包括编译期就已经明确的数值字面量,也包括到运行期解析后才能够获得的方法或者字段引用。此时不再是常量池中的符号地址了,这里换为真实地址
运行时常量池,相对于class文件常量池的另一重要特征是:具备动态性

在这里插入图片描述

Hotspot中方法区的变化:

只有Hotspot存在永久代,BEA JRockit、IBM J9等来说,是不存在永久代的概念的。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

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

元空间与永久代最大的区别就是:
永久代数据是分配在虚拟机内存当中的,初始化内存大小不好确定。
元空间则是放在了与虚拟机不相关的本地内存上,元空间的内存大小仅受本地内存大小的限制
1)为永久代设置空间大小是很难确定的。在某些场景下,如果动态加载类过多,容易产生Perm区的OOM 。比如某个实际web工程中,因为功能点比较多,在运行过程中,要不断动态加载很多类,经常出现致命错误。
2)永久代不好优化。

StringTable(字符串常量池)为什么要调整?

jdk7中将stringTable放到了堆空间中。因为永久代的回收效率很低,在full gc的时候才会触发。而full gc是老年代的空间不足、永久代不足时才会触发
而我们开发中会有大量的字符串被创建,回收效率低,导致永久代内存不足放到堆里,能及时回收内存

静态变量放在哪里?

在这里插入图片描述

staticobj随着Test的类型信息存放在方法区的静态变量
instanceobj随着Test的对存放在Java堆,
localobject则是存放在foo()方法栈帧的局部变量表中。

结论:

静态引用对应的对象实体始终都存在堆空间

方法区的垃圾回收

在这里插入图片描述

方法区的垃圾收集主要回收两部分内容:
常量池中废弃的常量和不再使用的类型。
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值