[java虚拟机]--(1)java内存区域--(2)线程间共享区域

声明:

Author:赵志乾

Date:2018-6-18

Declaration:All Right Reserved!!!


背景知识:

[java虚拟机]--(1)java内存区域--(1)线程私有区域

虚拟机内存之线程间共享区域:

1、堆

    谈及内存区域的划分,一般会将内存区域简单的划分为堆内存和栈内存。当然,这只是一种粗粒度的划分,详细的划分见《java内存区域》。对于开发而言,堆内存相较于栈内存,其生命周期更具可管理性。因为栈是依据线程调用层级自行构建的,开发人员在这一过程中,并没有对栈内存进行管控的机会。每个栈帧的生命周期都是始于对应方法的调用、止于方法的结束。而堆内存的分配和回收权限在不同的应用中,则有不同的规定:

    C++应用:堆内存的分配和回收完全由开发人员来控制。遵循“谁申请、谁释放,谁创建、谁销毁”的原则。这也是C++应用中容易出现内存泄漏的原因。

    Java应用:堆内存的分配由开发人员控制,而回收则由虚拟机来控制。虚拟机能够依据堆内存的使用情况进行批次回收,从而降低应用中内存泄漏的风险。

    虚拟机中的堆内存是各区域中占比最大的一块,也是gc线程回收内存的重点区域。当堆内存占满,无法做进一步申请时,会抛出OutOfMemoryError异常。由于堆内存为线程间共享,所以使用堆内存可以很方便的实现线程间的通信,也因其为多线程操作,并发访问时需要开发人员保证共享区域的线程安全性。

注:堆内存是虚拟机规范中唯一用于存放对象实例的区域,但在虚拟机的具体实现中,这一描述并不准确。

2、方法区

    方法区的概念源于CPU所管理内存中的代码段。在冯诺伊曼架构体系中,代码和数据分开存储,CPU会分别从代码段取得指令、数据段取得操作数进行计算。虚拟机规范中,则将代码段的概念迁移到方法区。

    方法区虽源于代码段,但在虚拟机中,其方法区存储的内容不止代码。还包括静态变量、常量、类信息等等。其中最为出名的就是运行时常量池。

    运行时常量池会存放字节码文件中的常量池内容,也包括在类加载阶段翻译出来的直接引用。其相较于文件中的常量池,最大的特点就是具有动态行,即应用运行期间会有新的常量加入运行时常量池。运行时常量池中的内容也会由gc线程进行回收,但不是强制要求(因为对于整个方法区而言,gc效果并不显著)。故在不同的虚拟机实现中,实现的机制也大不相同。

注:因为方法区在应用运行期间,会有内容不断的加入。所以当没有内存可用时,其也会抛出OutOfMemoryError异常。


邮箱:[email protected]

参考资料:《深入理解java虚拟机》--周志明



猜你喜欢

转载自blog.csdn.net/zhaoyaxuan001/article/details/80723774