JVM java虚拟机运行时数据区域

Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。

这些区域用途不同,有各自的创建和销毁时间。

下图是JVM所管理的内存将会包括下图的数据区域:

(字符串常量池存在于堆中)

JVM运行时数据区

Notes:

1.程序计数器

是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域。

2.Java堆

Java堆是Java虚拟机所管理的内存中最大的一块,是被所有线程共享的一块内存区域,唯一目的就是存放对象实例,几乎所有的对象实例都在堆上分配内存。

Java堆是垃圾收集器管理的主要区域,也叫“GC堆”。Java堆中可细分为:新生代与老年代;再细致一点,有Eden空间、From Survivor空间、To Survivor空间等。

Java堆可以处于物理上不连续的内存空间中,逻辑上连续即可。堆在实现时候,既可以实现成固定大小的,也可以是可扩展的(主流都是可扩展的,通过-Xmx和-Xms控制)。如果在堆中没有内存完成实例分配,并且堆也无法扩展时,将会抛出OutOfMemoryError异常。

3.方法区

线程共享的内存区域。他的作用是:存储已被JVM加载的类信息、常量、静态常量、即时编译器编译后的代码 等数据。

内存回收在该区域主要针对常量池的回收、对类的卸载。

当方法区无法满足内存分配需求时,将抛出OutOfMemoryError异常。

3.1 运行时常量池

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

class文件中除了有类的版本、字段、方法、接口等描述信息外,还有一项是常量池,用于编译期生成的各种字面量和符号引用等内容,这部分内容将在类加载后进入方法区的运行时常量池中存放。

JVM对class文件每一部分的格式都有严格规定,但对于运行时常量池,JVM没有任何细节的要求。不过,除了Class文件中描述的符号引用外,还会把翻译出来的直接引用也存储在运行时常量池中。

运行时常量池相对于Class文件常量池的另一个重要特征是具备动态性,Java并不要求常量一定只有编译期才产生,换言之,并非预置入Class文件中常量池的内容才能进入方法区运行时常量池,运行期间也可能将新的常量放入池中。如String类的intern()方法。

当常量池无法再申请到内存时候,会抛出OutOfMemoryError异常。

发布了22 篇原创文章 · 获赞 21 · 访问量 2085

猜你喜欢

转载自blog.csdn.net/weixin_41532316/article/details/102385179
今日推荐