深入理解Java虚拟机——Java内存区域与内存溢出异常(读书笔记)

运行时数据区域

1、程序计数器:

较小的内存空间,线程私有,当前线程所执行的字节码的行号指示器,字节码解释器工作时,就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,如果执行的Native方法,计数器的值为空,不会产生异常情况。

2、Java虚拟机栈:

线程私有,描述的是Java方法执行的内存模型,每个方法对应一个栈帧(Stack Frame)存储局部变量表、操作栈、动态链接、方法出口等信息,每一个方法被调用到执行完成,对应一个栈帧在虚拟机栈中的入栈到出栈。

局部变量表存放编译期可知的各种基本数据类型、对象引用、returnAddress类型,long和double类型的数据会占2个局部变量空间(slot),其余占一个,局部变量表所需的内存空间在编译期间完成分配。

当线程请求的栈深度大于JVM所允许的深度,抛出StackOverFlowError;

当JVM可以动态扩展时,无法申请到足够的内存时会抛出OutOfMemoryError

3、本地方法栈:

与虚拟机栈类似,区别是本地方法栈为JVM使用到的Native方法服务

有的虚拟机(如:HotSpot)直接把本地方法栈和虚拟机栈合二为一

4、Java堆:

JVM所管理内存中最大的一块,线程共享,JVM启动时创建,存放对象实例,垃圾收集器管理的主要区域。

Java堆可以处于物理上不连续的空间,只要逻辑上是连续的。

当堆中没有内存完成实例分配,并且堆也无法再扩展时,会抛出OutOfMemoryError

5、方法区:线程共享,存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

垃圾收集行为较少,内存回收的目标主要是常量池的回收、类型的卸载

当无法满足内存分配需求时,抛出OutOfMemoryError

运行时常量池:

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

对象的访问方式

1、使用句柄:

2、直接访问:

调节参数

设置堆大小

-Xms   -Xmx

设置栈大小:

-Xss

设置常量池的大小:

-XX:PermSize   -XX:MaxPermSize

猜你喜欢

转载自blog.csdn.net/sanmao123456_/article/details/82942231
今日推荐