39.JVM运行时数据区之方法区概述

 

1.运行时数据区简单回顾

运行时数据区划分为下图所示的五个部分:
在这里插入图片描述
从线程共享与否的角度,可以划分为线程共享的堆和元空间。线程私有的是栈区、程序计数器、本地方法栈。
1.除了程序计数器,其它的区域都存在OOM,其中栈区和本地方法栈还存在StackOverflow
2.堆区和元空间存在GC。其它不存在GC
在这里插入图片描述

2.栈、堆、方法区的交互关系

从一行简单的代码看它们三者之间的关系:

Person person = new Person();

1.Person类型信息放在了方法区(JDK8及以后称为元空间);
2.person变量存放在栈区,new这个对象肯定实在一个方法中进行的,一个方法对应一个栈帧,栈帧中有局部变量表,person变量就存放在局部变量表中。
3.new Person()创建出来的实例变量就存放在堆区(不是绝对,但因为还可以防止栈上,但是大部分情况都是放在堆区)。

在这里插入图片描述

3.方法区的理解

1.虽然Java虚拟机规范规定了方法区在逻辑上是属于堆的一部分,但是HotSpot JVM实现的时候,是将方法区和堆区分开的。
所以,方法区看作是一块独立于Java堆的内存空间。
在这里插入图片描述
2.方法区是线程共享的。
3.方法区在JVM启动的时候创建,实际物理内存可以不连续。
4.方法区的大小和堆区一样,可以固定大小或者可扩展。
5.方法区的大小,决定了它能够保存的类的个数,如果系统定义了太多的类,就会导致方法区溢出。(也就是能够加载的类的个数,如果方法区很小,那么程序运行的时候,加载到内存中的类的个数就不能太多,否则会出错。)
6.关闭虚拟机,方法区的内存区域就会被释放。
在这里插入图片描述

4.HotSpot中方法区的演进过程

1.JDK7及以前,习惯上把方法区称为永久代;JDK8及以后,使用元空间取代了永久代。
方法区是虚拟机规定的一个概念,永久代和元空间是落地实现。
可以把方法区看做是接口,永久代和元空间看做是接口的实现。
2.在HotSpot虚拟机中,方法区和永久代是等价的。但是在别的虚拟机中,就不一定了,例如IBM J9虚拟机的实现,根本就不存在永久代的概念。
在这里插入图片描述
3.JDK7中方法区的落地实现是永久代。
4.JDK8及以后方法区的落地实现是元空间。
在这里插入图片描述
5.JDK8及以后的元空间与永久代的最大的区别在于:元空间不在虚拟机设置的内存中,而是直接使用的本地内存。
6.方法区无法满足新的内存分配需求时,将抛出OOM
在这里插入图片描述

 

posted @ 2020-11-18 16:34  跃小云  阅读(138)  评论(0编辑  收藏  举报