JVM原理与实战
一、Java虚拟机概述
java程序通过虚拟机实现了java代码的跨平台。
二、java虚拟机运行过程:
类编译器编译java代码为class文件,
类加载器将class文件加载到jvm,
程序计数器控制程序的执行,
虚拟机栈存放局部变量,方法名,
堆存放java对象,
方法区存放常量及静态变量等,
jvm垃圾回收机制回收堆中内存。
三、内存模型
程序计数器:当前线程所执行的字节码的行号指示器,指向虚拟机字节码的位置。
虚拟机栈:
栈是线程私有的内存空间。在栈中保存的主要内容是栈帧。
方法被调用称为入栈,执行完毕就是出栈。
创建一个栈帧用于存储局部变量表、操作数栈、帧数据区等。
java堆是完全自动化管理,垃圾自动回收。
方法区是线程共享的,用于存储类信息。
元数据区:元空间并不在虚拟机中,而是使用的堆外的直接内存。
四、垃圾回收
可触及性:从根节点开始是否可以访问到某个对象,也说明这个对象是否被使用。
分为三种:可触及;可复活;不可触及
四种引用级别:
强引用、软引用、弱引用、虚引用
槽位复用
对象分配:栈上分配、TLAB分配、老年代分配、新生代分配。
栈上分配速度快,并且可以有效避免GC带来的负面影响。
标量替换:不可被分解的量,java的基础数据类型;聚合量是可以被分解的量。
TLAB:线程本地分配缓存区
垃圾回收法:
引用计数法:统计引用计数,引用少的先回收
标记清除法:标记+清除
复刻算法:内存分为两块,A内存存活对象复刻到B内存,清除掉A内存,使用B内存
标记压缩法:标记存活的对象,将所有存活的对象压缩到内存的一端,清理所有存活对象之外的空间。
分代算法:分为新生代和老年代,新生代采取复刻算法比较合适,老年代采用标记清除或标记压缩算法。
分区算法:分为连续的不同小区间。
五、垃圾收集器
串型回收器Serial收集器,单线程。适用于单核cpu。
新生代串行回收器采用:复刻算法
老年代串行回收器采用:标记压缩算法
将串行回收器并行化。
ParNew是一个新生代回收器,与串行回收器唯一不同的,就是采用并发方式执行GC。
ParallelGC回收器也采用的复制算法,提供一些设置系统吞吐量的参数用来控制GC行为。
ParallelOldGC,老年代的回收器。
并行回收器CMS,标记清除算法,多线程并发执行器,关心系统的停顿时间。
并行回收器CMS
1,初始标记
2,并发标记
3,预清理
4,重新标记
5,并发清理
6,并发重置
G1收集器:新生代GC,并发标记周期,混合收集,Full GC
新生代GC主要工作就是回收eden区和surivor区。
初始标记:标记从根节点直接到达的对象。
根区域扫描
并发标记
重新标记
六、JVM常用参数:
初始化内存/最大堆内存/GC日志
JVM监控优化
top命令:系统统计信息,进程信息
任务队列信息
vmstat命令:统计cpu,内存使用情况。
iostat工具
jps查看java进程
jstat:用于查看堆中的运行信息。
jinfo:用于查看运行中java进程的虚拟机参数
jmap:用于生成指定java进程的dump文件。用于查看堆内对象实例的统计信息。
jhat:命令用于分析jmap生成的堆快照。
jstack:用于导出指定java进程的堆栈信息。
jcmd:用于导出指定java进程的堆栈信息。