深入理解java虚拟机-第一章:java虚拟机内存结构


1.结构分布

深入理解java虚拟机-第一章:java虚拟机内存结构

2.每个区域解析

深入理解java虚拟机-第一章:java虚拟机内存结构



--------------割---------------

以下为****上编辑的,版本很难看,上面的Excel整理版。


   模块名称                                           线程                             作用 存储对象                备注    
程序计数器 私有 当前线程所执行字节码的行号指示器,
通过改变这个计数器的值来选取下一条将要执行的字节码指令。
数字 每个线程都会有一个,线程之间互不影响,独立存储。
共享 垃圾收集器管理的主要区域;
可以处于物理上不连续而逻辑上连续的内存空间中。

对象实例 内存中最大一块;
可扩展;

-Xms参数设置初始值

-Xmx参数设置最大值

内存不够分配实例存储空间时抛出OutOfMemoryError异常
虚拟机栈 私有

描述的是java方法执行的内存模型:每个方法在执行的同时多会创建一个栈帧用于存储局部变量表、操作数栈、动态链表、方法出口等信息。

每一个方法从调用直至完成的过程,就对应着一个栈帧在虚拟机中入栈到出栈的过程。

局部变量表:存放了编译期可指的基本类型(8大类型)、对象引用(引用指针,句柄)、returnAddress类型。


生命周期与线程相同;
如果线程请求的栈深度大于虚拟机允许的深度,会报StackOverFlowError;
如果虚拟机栈扩展无法获取做够的内存空间时,会报OutOfMemoryError。
本地方法栈

为虚拟机用到的native方法服务。


方法区 共享 别名:永久代
用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据;



运行时常量池                     
是方法区的一部分; 编译期生成的字面量和符号引用  

3.对象访问

java最简单的对象访问,也会涉及到java栈、java堆、方法区三个重要的部分。

以Object object = new Object();为例:

Object object   这部分语义将反映到java栈中的本地变量表中,即reference引用。

new Object() 这部分语义反映在java堆中,形成了存储Object类型所有数据值的结构化内存。注:在java堆中还必须存储有能找到此对象类型数据(对象类型、父类、实现接口、方法),这些类型数据存储在方法区中。

引用访问java堆中对象具体位置的方式有两种:句柄和直接指针。
a)句柄
使用句柄方式访问对象,则会在java堆中划分出一块内存作为句柄池,引用中存储的是对象的句柄地址;
句柄中存储了对象实例地址和类型数据的地址。
优点:引用中直接存储的是稳定的句柄地址,在对象被移动的情况下不需要改变引用,而是改变句柄中的实例数据指针。

深入理解java虚拟机-第一章:java虚拟机内存结构

b)直接指针
使用直接指针的方式,在java栈中的引用将直接存储对象地址;但是在java堆的布局中就必须考虑如何设置访问类型数据的相关信息。
优点:访问速度快,相比较于句柄访问对象的方式而言,节省了一次指针定位的时间开销。
深入理解java虚拟机-第一章:java虚拟机内存结构

4.java堆溢出和栈溢出


a.堆溢出抛出 java.lang.OutOfMemoryError。
可能原因:
1)内存泄露。垃圾回收器不能自动回收。
2)实际所需内存值过大,或者对象生命周期过长或者持有时间过长。
解决办法:
java堆参数设置:-xms 堆最小值;-xmx 堆最大值 。

b.栈溢出
深入理解java虚拟机-第一章:java虚拟机内存结构
解决办法:
栈对应的设置参数为:-Xss 栈容量。
c.运行时常量池溢出
因为运行时常量池分配在方法区内,我们可以通过 -XX:PermSize 和 -xx:ManPermSize来限制方法区的大小来解决。
d.本地直接内存溢出
通过 -XX:MaxDirectMemorySize 来设定。





深入理解java虚拟机-第一章:java虚拟机内存结构
深入理解java虚拟机-第一章:java虚拟机内存结构

深入理解java虚拟机-第一章:java虚拟机内存结构