《深入理解Java虚拟机-JVM高级特性与最佳实践》
1.Java运行时数据区域
A.程序计数器:当前线程所执行字节码的行号指示器,线程私有(非共享)。对于Java方法,执行的是虚拟机字节码的指令地址;如果是Native方法,计数器值为空。该区域是运行时区域中唯一未规定OutOfMemoryError的区域。
B.Java虚拟栈:存放Java方法执行时栈帧数据(存储局部变量、操作数栈、动态链接、方法出口灯),线程私有(非共享),生命周期与线程相同。线程深度大于虚拟机所允许深度,抛出StackOverflowError异常;对于支持扩展的虚拟机,如果无法申请足够内存,抛出OutOfMemoryError异常。
C.本地方法栈:类似于Java虚拟栈,但存放的是Native方法。
D.Java堆:虚拟机启动时创建,存放对象实例,所有线程共享。Java堆是GC管理的主要区域。堆无法扩展时抛出OutOfMemoryError异常。
E.方法区:存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据,所有线程共享。方法区无法满足内存分配时抛出OutOfMemoryError异常。在HoSpot虚拟机上,该区域也称之为永久代(通过-XX:MaxPermSize设置上限),HotSpot虚拟机将GC分代扩展到了方法区,省去专门编写内存管理代码的工作。
F.运行时常量池:是方法区的一部分,存放编译器生成的各种字面和符号引用。运行时常量池具备动态性,运行时可以将新的常量加入到常量池,比如String中的intern方法。常量池无法申请内存抛出OutOfMemoryError异常。
2.对象的创建过程(使用new)
A.在常量池中定位一个类的符号引用,检查是否加载、解析和初始化(如果没有,执行类加载过程)。
B.为新生对象分配内存,内存大小在类加载时便可以确定。分配方式包括指针碰撞(java内存规整,连续存放)和空闲列表(java内存交错使用,通过表记录使用情况)。
C.将分配的内存初始化为零值。
D.类对象信息设置,如类的元数据信息、对象的哈希码、对象的GC分代年龄等信息。
3.对象的内存布局:
A.对象头:包括对自身运行时数据(哈希码、GC分代、锁状态等)和类型指针(对象指向它的类元数据的指针)。
B.实例数据:代码中定义的各种类型的字段内容。
C.对齐填充:占位补齐。
4.对象的访问定位:通过栈上的引用数据来操作堆上的具体对象。
5.JVM常用设置:
A.-Xms20m -Xmx20m:指定Java堆最小、最大值
B.-XX:HeapDumpOnOutOfMemoryError:虚拟机抛出异常是Dump出当前内存堆快照。 -XX:HeapDumpPath指定Dump出文件的位置。
C.-Xss:指定栈内存容量。
D.-XX:PermSize和-XX:MaxPermSize限定方法区内存大小,可以间接限制常量池的内容。
E.-XX:MaxirectMemorySize限定直接内存大小,不指定默认与-Xmx指定的堆内存一样。
6.分析JVM所Dump出的文件,可以使用Eclipse Memory Analyzer分析内存泄漏或者溢出。
1.判断是否垃圾收集的方法:
A.引用计数算法:无法解决循环引用问题,JVM不使用。
B.可达性分析算法:当一个对象到GC Roots没有任何引用链(也称作不可达)就说明对象时不可用的。可作为GC Roots的有:虚拟机栈中引用对象、方法区中的静态属性引用的对象、方法区中常量引用的对象和本地方法栈中JNI引用的对象。
2.引用种类(引用强度依次递减):
A.强引用:最常用的通过new建立的引用。只要引用存在,GC永不回收。
B.软引用:描述有用但是非必须的引用。系统异常前先回收软引用对象,回收不成功再抛出异常。Java使用SoftReference类实现软引用。
C.弱引用:描述非必须的引用,较软引用强度更弱。只能生存到垃圾收集器工作之前,无论当前内存是否充足,都会回收掉弱引用的对象。Java使用WeakReference实现弱引用。
D.虚引用:也称幽灵引用或者幻影引用,最弱的引用关系。对象是否有虚引用完全不影响其是否垃圾回收,仅用于该对象被回收时受到一个系统通知。Java通过PhantomReference实现虚引用。
3.垃圾收集算法判断需要垃圾收集只是将对象判了“缓刑”,并不会立即收集到对象。收集对象需要经过两次标记的过程:
A.可达性分析没有与GC Roots的引用链,对象会被进行第一次标记并进行一次筛选。筛选条件是判断对象是否有必要执行finalize()方法:对象没有覆盖finalize()方法或者finalize()方法已经被虚拟机调用(finalize方法只调用一次!!!),标记为没必要执行。如果判定为有必要执行,JVM会将其放入F-Queue队列中,并在稍后一个由虚拟机自动创建的、低优先级的Finalizer线程去执行。这里的执行仅仅是触发这个方法,不承诺等待期结束(防止finalize方法执行缓慢导致整个内存回收系统崩溃)。
B.如果在finalize()方法中对象没有自救(比如将自己的this指针赋值给一个静态变量),那么JVM会进行第二次标记,将其溢出F-Queue并最终回收掉。
4.方法区中对象收集需要满足:
A.该类所有实例已经回收。
B.加载该类的ClassLoader已经回收。
C.该类对应的java.lang.Class对象没有任何地方被引用。
HotSpot虚拟机提供-Xnoclassgc参数进行控制,还可以使用-verbose:class以及-XX:+TraceClassLoading、-XX:+TraceClassUnLoading查看类加载和卸载信息。
5.垃圾收集算法:
A.标记-清除算法:分为标记和清除两个阶段。有两个不足:效率不高和产生内存碎片。
B.复制算法:将内存划分为两份,清理时将从存活的放到另一份,然后原先的全部清理,用于新生代内存清理。Hotspot将内存分成三份:Eden和2个Survivor,其比例为8:1,新生代可以使用的为8+1,另一份用于清理后的对象内存赋值。如果这一份Survivor内存不足以存放清理过得对象,就需要采用分配担保机制将对象放到老年代上。
C.标记-整理算法:标记清理后进行内存整理,防止内存碎片。
D.分代收集算法:分为新生代和老年代。新生代的特点是“朝生夕死”,采用复制算法;老年代对象存活率较高,多采用标记-清理或者标记-整理算法。
6.HotSpot算法实现:
A.枚举根节点:为了保证一致性,必须所有进程都停止,称之为STOP THE WORLD。类加载完成后,通过OopMap的数据结构存储类信息,达到快速枚举根节点。
B.安全点:程序执行不能再所有地方都能停下来,需要在特定的地点(安全点)才能停下来。在安全点停下有两种方式:抢先式中断(先中断然后如果不在安全点就恢复线程,跑到安全点上,暂时没有虚拟机使用)和主动中断(中断时设置标志,所有线程轮询)。
C.安全区域:针对程序休眠或者blocked状态,需要安全区域保证区域内的代码引用关系不会发生变化,在安全区域中的任何一个地方进行GC都是安全的。
7.垃圾收集器:
A.Serial收集器:单线程收集器,收集时必须STOP THE WORLD(停止所有线程)。新生代复制算法,老年代标记-整理算法。无进程切换开销适合虚拟机运行在Client模式时使用。
B.ParNew收集器:Serial的多线程版本。适合虚拟机Server模式使用。
C.Parallel Scavenge收集器:专门针对可控制吞吐量设计的收集器。通过-XX:GCTimeRatio参数设置吞吐量大小(值为X表示最大gc时间占总时间的1/(1+X))。
D.Serial Old收集器:Serial收集器的老年代版本。
E.Parallel Old收集器:Parallel Scavenge收集器的老年代版本。
F.CMS(Concurrent Mark Sweep是以获取最回收停顿为目标的收集器。分为:初始标记(STW)-并发表及(多线程)-重新标记(STW)-并发清除(多线程)四个阶段。CMS收集器无法处理浮动垃圾(标记过程后产生的垃圾)。对于老年代,CMS运行期间预留的内存无法满足程序时会出现Concurrent Mode Failure失败,因此需要使用Serial Old处理老年代的数据。CMS老年代使用的是标记-清除算法。
G.G1(Garbage-First)收集器:最大特点是可预测的停顿和空间整合(标记-整理算法)。也分为初始标记-并发标记-最终标记-筛选回收四个阶段。
8.内存分配和回收策略:
A.对象在新生代Eden中分配,当Eden没有足够空间,虚拟机会发生一次Minor GC(新生代)。老年代发生的是Major GC。
B.大对象直接进入老年代,通过-XX:PretenureSizeThreshold设置大对象的大小。
C.长期存活对象直接进入老年代:经过一次Minor GC没被清理后年代增加一岁。通过-XX:MaxTenuringThreshold设置进入老年代的年龄。-Xmn10m设置新生代大小。
D.动态对象年龄判断:如果在Survivor空间中相同年龄所有对象大小的综合大于Survivor空间的一半,年龄大于或等于该年龄的对象自动进入老年代,无需年龄规定的限制。
1.jps:虚拟机进程状态工具。
2.jstat:虚拟机统计信息监视工具。
3.jinfo:java配置信息工具。
4.jmap:java内存映像工具。
5.jhat:jvm heap analysis tools。
6.jstack:java堆栈跟踪工具。
7.可视化工具:JConsole和VisualVM。
Chap 5调优案例分析与实战
略