Java虚拟机
Jvm机制
- 装载具有合适的类名或者接口
- 执行已装载的类或者接口中的指令
Jvm内存结构
-
方法区:这块区域所有线程共享的,用来存放类的信息(如类名,修饰符),如常量,静态变量,构造函数等。GC对这块区域的回收主要是针对常量和类的装载, 在Hotspot虚拟机中,这块区域对应持久代
但是JDK8后,持久代被删除替换为元空间,不在占用虚拟机内存 -
堆:这块区域也是所有线程共享的,用来存放对象的实例,绝大多数创建的对象都存放在这里.垃圾回收器最主要针对的对象,对这部分的回收效率影响了VM的整体性能。
堆中的空间划分:(基于最新的JDK8)
- 新生代(Young Generation):包括一个Eden(伊甸园)和两个Surviver(幸存者)
- Eden:大多数对象刚创建都会被保存在这块区域(除了部分大对象创建的时候,通过内存担保机制直接保存都Old以外).因为大多数对象都是短期内使用,
所以会触发Minor GC[1],CG通过回收这部分区域
- Surviver[2](个人称为亚当和夏娃):当Eden满了后进行GC,还存活的对象将复制到亚当或者夏娃其中一个,当亚当或者夏娃(假设是亚当)其中一个满了后,将会GC并把存活的对象
复制到另外一个(这个为夏娃)的空间内,当这个(夏娃)也满了以后,会把从第一个(亚当)存活下来的对象放到Old中.
- 老年代(Old Generation):该区域是属于老年代,一般能够在Surviver中没有被清除出去的对象才会进入到这块区域,该区域主要是采用标记清除算法[3] -
栈:这块区域为线程独有的,主要用来维护栈针.因为栈中的数据符合先进后出的规则,每调用一个方法就创建一个栈针,然后存放在栈中,
方法调用完成后,把栈针释放,这样就可以继续执行后续的方法了 -
本地方法栈:这块区域为VM的Native方法,无需关心
指令计数器
这是一个特殊的内存区域,不占用RAM,而是在CPU上,目的是保存当前字节码执行到的行号
垃圾收集器
GC主要是由垃圾收集器来进行执行的,采用不同的GC算法
- 串行收集器:
启用串行收集器: -XX:+UseSerialGC
新生代中使用Serial收集器采用Coping算法,单一线程进行GC,其他工作线程都挂起。
老年代中使用Serial Old收集器采用MC算法,单一线程进行GC,其他工作线程都挂起。
- ParNew(多线程版本新生代Serial收集器):
多线程开关: -XX:+UseParNewGC -XX:ParallelGCThreads 控制线程数量
使用Coping算法,多线程进行GC,其他工作线程都挂起
- 并行收集器:
启动并行收集器: -XX:+UseParallelGC (新生代用多线程、老年代用单线程)
启动并行收集器: -XX:+UseParallelOldGC (新生代和老年代都用多线程)
设置最大gc停顿时间: -XX:MaxGCPauseMills
gc时间占比: -XX:GCTimeRatio
自适应调节策略开关: -XX:+UseAdaptiveSizePolicy
新生代中使用Parallel Scavenge 采用 Coping算法,多线程进行GC,其他工作线程都挂起,但是这个收集器更加关系CPU的吞吐量,所以能控制GC时间,而ParNew不行.自适应调节策略,自动调节各种参数,新手福音
老年代中使用 Parallel Old 采用MC 算法,多线程进行GC
-
CMS收集器(Concurrent Mark Sweep):
启用CMS收集器:-XX:+UseConcMarkSweepGC
设置线程数:-XX:ParallelCMSThreads=n老年代中使用CMS采用MS算法,多线程并发,所以停顿低,速度快,但是因为采用MS算法,所以会有碎片产生
网友评论