JVM的基本组成:类加载器、运行时数据区、执行引擎、本地接口
运行时数据区分为:方法区、虚拟机栈、本地方法栈、堆、程序计数器
其中程序计数器是唯一不会发生内存泄漏和内存溢出的部分
判断对象已死的算法:
1、引用计数器法:给对象添加一个引用计数器,每当有一个地方引用该对象时,计数器+1;当引用失效时,计数器-1。任何时刻,当计数器为0时,该对象不在被引用。(当前的主流JVM均不采用该方法)
优点:实现简单,判定效率也高;
缺点:很难解决对象之间互相循环调用的情况。
2、可达性分析算法:通过一系列的成为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径成为引用链,当一个对象到“GC Roots”没有任何引用链相连,则证明此对象是不可用的。
在Java中,可以作为GC Roots的对象包括:
(1)虚拟机栈中引用的对象;
(2)方法区中类静态属性引用的对象;
(3)方法区中常量引用的对象;
(4)本地方法栈中JNI(即一般说的Native方法)的引用的对象
四种引用(强度依次递减):
1、强引用
在代码中普遍存在,类似于String s=new String(),只要强引用一直存在,垃圾收集器就永远不会回收被引用的对象。
2、软引用
用来描述一些还有用但非必须的对象,当内存溢出异常发生之前,通过垃圾回收进行二次回收。用SoftReference类来实现软引用。
3、弱引用
用来描述非必须的对象,它仅仅能生存到下一次垃圾回收之前,当垃圾收集时,无论内存是否足够,它都要被回收。用WeakReference类来实现弱引用。
4、虚引用
一个对象是否有虚引用的存在,完全不会对其生存时间构成影响。无法通过一个虚引用来获取一个实例对象。为一个对象设置虚引用的唯一目的就是该对象在垃圾回收时收到一个系统通知。用PhantomReference类来实现虚引用。
垃圾收集算法:
1、标记-清除算法
2、复制算法
3、标记-整理算法
4、分代垃圾回收
分为老年代和年轻代,年轻代又分为Eden区和Survivor区。
垃圾收集器:
1、Serial收集器
2、ParNew收集器
3、Paraller Scavenge收集器
4、Serial Old收集器
Serial收集器的老年代版本,是一个单线程收集器,使用标记-整理算法。主要目的是在Client模式下使用。
在Server模式下使用,有两种用途:
(1)在jdk5以前的版本中配合Paraller Scanvenge收集器使用;
(2)作为CMS的备用方案,在并发收集发生Concurrent Mode Failure时使用。
5、Paraller Old收集器
6、CMS收集器
CMS的三大缺点:
(1)CMS收集器对CPU资源非常敏感
(2)无法处理浮动垃圾
(3)因为基于标记-清除算法,所以会有大量的内存碎片产生
G1收集器:
设计原则:简单可行的性能调优
在最终标记阶段,G1通过三色标记算法修正了CMS会出现错标的问题
JVM常见的参数设置
JVM参数
参数 描述
-Xms 设置JVM启动时初始化堆大小
-Xmx 设置堆的最大值
-Xmn 设置年轻代的大小
-XX:PermGen 设置老年代的初始化大小
-XX:MaxPermGen 设置老年代的最大值
-XX:SurvivorRatio 设置Eden区和Survivor区的比例,默认为8
-XX:NewRatio 设置老年代和年轻代的比例,默认为2
GC参数
参数 描述
-XX:+UseSerialGC client模式下默认值,打开此开关后,采用Serial+Serial Old组合进行垃圾回收
-XX:UseParallelGC 采用Parallel Scanvenge+Serial Old组合
-XX:UseParallelOldGC Parallel Scanvenge+Parallel Old
-XX:UseNewGC ParNew+Serial Old
-XX:UseConcMarkSweepGC ParNew+CMS+Serial Old
-XX:UseG1GC 使用G1收集器



