jvm内存学习

Jvm学习

一、Jvm内存划分

Jvm内存主要划分为以下几个模块

 jvm内存学习

二、程序计数器(Program Counter Register

程序计数器是线程私有的,每一个线程有一个。

与cpu中的pc寄存器相似,用来只是当前的线程执行到了字节码的哪一行。

jvm当前执行的是一个java方法,则程序计数器记录的是当前放的字节码地址;如果执行的是一个本地方法,则程序计数器存放的是Undefined

三、虚拟机栈(JVM Stack

虚拟机栈是线程私有的,每一个线程有一个。

一个线程的每个方法被执行的时候,都会创建一个栈帧。

栈帧中有局部变量表,操作站,动态链接,方法出口等。

方法被调用时,栈帧入栈,方法执行完成时,栈帧出栈。

局部变量表中存储着方法的局部变量,包括基本类型,对象的引用,返回地址等。

在局部变量表中,只有longdouble类型会占用2个局部变量空间(Slot,对于32位机器,一个Slot就是32bit),其它都是1Slot

虚拟机栈定义了2中异常。当线程调用的栈深度超过了栈的最大深度,会抛出StatckOverFlowError异常。当虚拟机栈没有被固定大小时,会不停的申请内存扩展大小,直到达到最大内存,会有OutOfMemoryError异常。

四、本地方法栈(Native Method Statck

本地方法栈是线程私有的,每一个线程有一个。

本地方法栈与虚拟机栈相似,唯一的区别是,虚拟机栈执行的是java方法,本地方法栈执行的native方法。但是在很多jvm中,两种栈是合在一起的。

五、堆区(Heap

堆区是线程私有的,每一个线程有一个。

堆区大致分为两个区域,或者叫两代。一个叫年轻代,一个叫老年代。

年轻代存储的刚创建的对象,年轻代又分为两个区域,Eden(伊甸)区和Survivor(幸存)区,survivor区有两个

① 对象刚刚被创建时,是分配在eden区的,eden区的内存是连续的,因此速度较快。

② eden区第一次满了之后,将会执行Minor GC,将过期的对象销毁,把幸存的对象复制到survivor0中(survivor0survivor1总有一个是空的)。

③ eden再一次满了,再进行一次Minor GC,会将幸存的对象复制到survivor1中。

④ 并且会将survivor0中的过期对象销毁,够资格的晋级年老代,幸存的进入survivor1中。

⑤ 当两个survivor区来回切换了几次后,大于等于15(这个值可配置-XX:MaxTenuringThreshold)的对象将会进入老年区。

 jvm内存学习

六、方法区(Method Area

方法区是各个线程共享的区域。

之前,Hotspot虚拟机把堆内存划分为 青年代,老年代,持久代。而方法区指的就是这个持久代。但其他大多数虚拟机都没有持久代,而Hotspot也已经取消了这个所谓持久代。

方法区,用于存储已经被虚拟机加载的类信息(即加载类时需要加载的信息,包括版本、field、方法、接口等信息)、final常量、静态变量、编译器即时编译的代码等。