内存区域
线程私有
1.程序计数器:当前线程执行的字节码的行号的指示器
2.虚拟机栈:存放方法的栈帧
栈帧:每个方法执行都会创建一个栈帧,伴随着方法从执行到完成。用于存储局部变量表,操作数栈,动态链接,方法出口等。
局部变量表:存放编译期可知的各种基本数据类型,引用类型,returnAddress类型。当进入一个方法时,这个方法需要在栈中分配多少空间是固定的。
StackOverflowError
2.本地方法栈:为虚拟机执行native方法服务,功能如虚拟机栈。
线程共享
1.堆:存放对象实例,垃圾收集器管理的主要区域,分为老年代和新生代
OOM异常 修改大小 -Xmx -Xms
2.方法区(元空间):存储运行常量池,虚拟机加载的类信息,静态变量,即时编译器编译后的代码等数据。
类信息:
类版本
字段
方法
接口
垃圾收集算法
GCRoot:
1.全局性的引用(例如常量或者静态属性)
2.执行上下文(栈帧中的本地变量表)
3.本地方法栈中JNI(即一般说的native方法)引用的对象。
垃圾收集器
1.Serial/Serial Old收集器:
(1)单线程垃圾收集器,回收过程需要暂停所有工作线程。
(2)单线程,没有切换线程的开销,效率较高
(3)用户桌面级应用,对于Client模式下的虚拟机来说是一个很好的选择
2.ParNew收集器,新生代收集器
(1)Serial收集器的多线程版本,回收过程中仍然需要暂停所有工作线程
(2)Server模式下首选收集器,只有它能与CMS收集器配合工作。
3.Parallel Scavenge收集器,新生代收集器
(1)其他收集器关注点不是缩短垃圾收集时用户的停顿时间,而Parallel Scavenge的目标是达到一个可控的
吞吐量。吞吐量就是CPU用于运行用户代码的时间与CPU总消耗时间的比值,即吞吐量 = 运行用户代码的时间 /
(运行用户代码的时间 + 垃圾收集时间)
(2)-XX:MaxGCPauseMillis 控制最大垃圾收集停顿时间
-XX:GCTimeRatio 直接设置吞吐量大小
4.Parallel Old收集器,Parallel Scavenge收集器老年代版本
(1)吞吐量优先
5.CMS(Concurrent Mark Sweep)收集器,老年代收集器
(1)以获取最短停顿时间为目标的收集器。
(2)执行过程分为四个步骤:
初始标记:Stop the World
并发标记
重新标记:Stop the World
并发清除
6.G1收集器,单独管理(老年代,新生代)
(1)并行与并发,分代收集,空间整合,可预测的停顿
(2)执行过程分为四个步骤
初始标记:Stop the World
并发标记
最终标记:Stop the World
筛选回收:Stop the World or not
内存分配
1.对象优先分配在Eden区:大多数情况下,对象在新生代Eden区中分配。当Eden区没有足够的空间进行分配时,
虚拟机将发起一次Minor GC。
2.大对象直接进入老年代:大对象是指需要大量连续空间的对象,例如很长的字符串,数组等,为了避免在Eden
区和两个Survivor区之间发生大量的内存复制。
3.长期存活的对象直接进入老年代:每熬过一次Minor GC年龄加一,超过15岁的对象晋升入老年代。
空间分配担保
新生代使用复制算法,可能出现大量对象在Minor GC后仍然存活,需要老年代进行空间分配担保,让Survivor
无法容纳的对象直接进入老年代,如果无法容纳,则进行Full GC。
逃逸分析和栈上分配
逃逸分析:分析出一个新的对象的引用的使用范围从而决定是否要将这个对象分配到堆上。