JAVA虚拟机运行时会将JVM使用的内存划分为不同的区域,每个区域负责不同的功能,以及各个区域的创建,销毁都各不相同。
下图是JVM运行时内存数据区的划分,
图1、JVM运行时数据区
1、程序计数器
每个线程都拥有一个独立的程序计数器,用于记录当前线程所要执行的字节码指令,该类内存区域为“线程私有”内存。
2、虚拟机栈
该区域也有人称为栈内存(对应java堆内存),这个叫法不完全正确,但可以便于理解。
该区域也是线程私有的,并且与线程的生命周期相同。
主要负责方法执行的内存部分,在每个方法执行时都会创建一个栈针,同时存储局部变量,操作数等方法相关信息。
局部变量表存储内容:主要是基本数据类型和对象的引用,而对象本身存储在堆中
每一次方法的调用到完成,都对应一个栈针在虚拟机栈中出入栈的过程。
该区域会抛出stackOverFlowError和OutOfMemoryError错误
stackOverFlowError 是线程请求的栈深度大于虚拟机允许的深度,如下面的代码
public static void main(String[] args) { testStackOverFlow(); } public static void testStackOverFlow(){ System.out.println("stackOverFLow"); testStackOverFlow(); }
OutOfMemoryError错误就是栈空间溢出,比如局部变量过多,占用内存过大,都会产生就不举例说明
3、本地方法栈
和虚拟机栈类似,只是负责本地Native方法,也会抛出stackOverFlowError和OutOfMemoryError错误,如IO中常用的文件读写操作的Native方法,可能是C语言或者其他语言的实现。
4、JAVA堆(JAVA Heap),GC堆
JAVA堆是JAVA虚拟机管理的内存,最大,最重要的部分,是所有线程共享的区域,
也是GC(垃圾回收)的主要回收部分,
再进行划分可以分为新生代,老生代(老年代);新生代可以划分为:Eden,From Survivor,To Survivor
主要存放对象实例,可以通过配置,设置不同代的大小和垃圾回收策略,很多优化也在堆上进行实现。
该区域会抛出 OutOfMemoryError异常
5、方法区(Method Area),非堆,永久代
该区域也是线程共享的内存区域,该区域也会进行垃圾回收,但可以忽略不计,因为效果很难令人满意
主要存储虚拟机加载的类信息,常量,静态变量等
该区域会抛出OutOfMemoryError异常,主要是启动时需要加载的类,常量,静态变量等信息特别多,超过了该区域设置的内存空间,就会抛出异常,
可以看看eclipse内存设置,如果将内存设置特别小就会抛出该内存溢出异常
运行时常量池:属于方法区的一部分,主要存储运行时常量,如String的intern方法产生的字符串常量。
6、直接内存
直接内存没有在图中显示,以为他并不是虚拟机运行时数据区的一部分,不归虚拟机管理,但该内存区域也会出现OutOfMemoryError异常,
该区域使用主要是在NIO的缓冲区的使用,会用到系统直接内存,因为是通过本地方法分配的内存,当本机无法分配更多的内存时就会抛出内存溢出异常
JVM相关术语:
S0C:年轻代中第一个survivor(幸存区)的容量 (字节)
S1C:年轻代中第二个survivor(幸存区)的容量 (字节)S0U:年轻代中第一个survivor(幸存区)目前已使用空间 (字节)
S1U:年轻代中第二个survivor(幸存区)目前已使用空间 (字节)
EC:年轻代中Eden(伊甸园)的容量 (字节)
EU:年轻代中Eden(伊甸园)目前已使用空间 (字节)
OC:Old代的容量 (字节)
OU:Old代目前已使用空间 (字节)
PC:Perm(持久代)的容量 (字节)
PU:Perm(持久代)目前已使用空间 (字节)
YGC:从应用程序启动到采样时年轻代中gc次数
YGCT:从应用程序启动到采样时年轻代中gc所用时间(s)
FGC:从应用程序启动到采样时old代(全gc)gc次数
FGCT:从应用程序启动到采样时old代(全gc)gc所用时间(s)
GCT:从应用程序启动到采样时gc用的总时间(s)
NGCMN:年轻代(young)中初始化(最小)的大小 (字节)
NGCMX:年轻代(young)的最大容量 (字节)
NGC:年轻代(young)中当前的容量 (字节)
OGCMN:old代中初始化(最小)的大小 (字节)
OGCMX:old代的最大容量 (字节)
OGC:old代当前新生成的容量 (字节)
PGCMN:perm代中初始化(最小)的大小 (字节)
PGCMX:perm代的最大容量 (字节)
PGC:perm代当前新生成的容量 (字节)
S0:年轻代中第一个survivor(幸存区)已使用的占当前容量百分比
S1:年轻代中第二个survivor(幸存区)已使用的占当前容量百分比
E:年轻代中Eden(伊甸园)已使用的占当前容量百分比
O:old代已使用的占当前容量百分比
P:perm代已使用的占当前容量百分比
S0CMX:年轻代中第一个survivor(幸存区)的最大容量 (字节)
S1CMX :年轻代中第二个survivor(幸存区)的最大容量 (字节)
ECMX:年轻代中Eden(伊甸园)的最大容量 (字节)
DSS:当前需要survivor(幸存区)的容量 (字节)(Eden区已满)
TT: 持有次数限制
MTT : 最大持有次数限制