1、哪些内存能够回收算法
JVM 的内存区域中,程序计数器、虚拟机栈和本地方法栈这 3 个区域是线程私有的,随着线程的建立而建立,销毁而销毁,所以不用回收。安全
垃圾回收的重点就是关注堆和方法区中的内存了,堆中的回收主要是对象的回收,方法区的回收主要是废弃常量和无用的类的回收。并发
2、何时能够被回收oracle
通常一个对象再也不被引用,就表明该对象能够被回收。目前有如下两种算法能够判断该对象是否能够被回收:工具
一、引用计数算法性能
这种算法是经过一个对象的引用计数器来判断该对象是否被引用了。每当对象被引用,引用计数器就会加 1;每当引用失效,计数器就会减 1。优化
当对象的引用计数器的值为 0 时,就说明该对象再也不被引用,能够被回收了。spa
虽然引用计数算法的实现简单,判断效率也很高,但它存在着对象之间相互循环引用的问题。线程
二、可达性分析算法日志
GC Roots 是全部对象的根引用。在垃圾回收时,会从这些 GC Roots 开始向下搜索,当一个对象到 GC Roots 没有任何引用链相连时,就证实此对象能够被回收。
目前 HotSpot 虚拟机采用的就是这种算法。
2.一、可做为GC Roots的对象:
Java虚拟机栈中的引用的对象 ;本地方法栈中JNI的引用的对象 ;方法区中的类静态属性、常量对象 。
以上两种算法都是经过引用来判断对象是否能够被回收。在 JDK 1.2 以后,Java 对引用的概念进行了扩充,将引用分为了如下四种:
3、回收算法
4、回收器/类型
5、GC 性能衡量指标
吞吐量:这里的吞吐量是指应用程序所花费的时间和系统总运行时间的比值。咱们能够按照这个公式来计算 GC 的吞吐量:系统总运行时间 = 应用程序耗时 +GC 耗时。若是系统运行了 100 分钟,GC 耗时 1 分钟,则系统吞吐量为 99%。
停顿时间:指垃圾收集器正在运行时,应用程序的暂停时间。对于串行回收器而言,停顿时间可能会比较长;而使用并发回收器,因为垃圾收集器和应用程序交替运行,程序的停顿时间就会变短,但其效率极可能不如独占垃圾收集器,系统的吞吐量也极可能会下降。
6、查看 & 分析 GC 日志
首先,咱们须要经过 JVM 参数预先设置 GC 日志,一般有如下几种 JVM 参数设置:
-XX:+PrintGC 输出 GC 日志
-XX:+PrintGCDetails 输出 GC 的详细日志
-XX:+PrintGCTimeStamps 输出 GC 的时间戳(以基准时间的形式)
-XX:+PrintGCDateStamps 输出 GC 的时间戳(以日期的形式,如 2013-05-04T21:53:59.234+0800)
-XX:+PrintHeapAtGC 在进行 GC 的先后打印出堆的信息
-Xloggc:../logs/gc.log 日志文件的输出路径
eg:-XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xloggc:/log/heapTest.log
若是GC日志很是大,能够用GCViewer工具打开日志文件,图形化界面查看总体的 GC 性能,以下图所示:
也能够用GCeasy工具,而且还能够将日志文件压缩以后,上传到 GCeasy 官网便可看到很是清楚的 GC 日志分析结果
7、回收调优
1. 下降 Minor GC 频率
Eden区存活的对象数量小,能够经过增大新生代空间来下降 Minor GC 的频率。
一般状况下,因为新生代空间较小,Eden 区很快被填满,就会致使频繁 Minor GC,所以咱们能够经过增大新生代空间来下降 Minor GC 的频率。
可能你会有这样的疑问,扩容 Eden 区虽然能够减小 Minor GC 的次数,但不会增长单次 Minor GC 的时间吗?若是单次 Minor GC 的时间增长,那也很难达到咱们期待的优化效果呀。
若是在堆内存中存在较多的长期存活的对象,此时增长年轻代空间,反而会增长 Minor GC 的时间。若是堆中的短时间对象不少,那么扩容新生代,单次 Minor GC 时间不会显著增长。所以,单次 Minor GC 时间更多取决于 GC 后存活对象的数量,而非 Eden 区的大小。
二、下降 Full GC 的频率
2.一、减小建立大对象
2.二、增大堆内存空间
2.三、选择合适的 GC 回收器
垃圾收集器的种类不少,咱们能够将其分红两种类型,一种是响应速度快,一种是吞吐量高。一般状况下,CMS (Concurrent Mark Sweep)和 G1 回收器的响应速度快,Parallel Scavenge 回收器的吞吐量高。
ps1:首先cms在1.9已经被标记为废弃,主要缘由在于标记清除下的悬浮内存,致使内存空间碎片化,进而致使fullGC的发生。不过其并行执行垃圾回收的性能仍是值得承认的,至少1.9后主推的G1在常规状况下也是不如它的效率好的。
ps2:G1与CMS的优点在于如下几点:
一、并行与并发:G1可以更充分利用多CPU、多核环境运行
二、分代收集:G1虽然也用了分代概念,但相比其余收集器须要配合不一样收集协同工做,但G1收集器可以独立管理整个堆
三、空间管理:与CMS的标记一清理算法不一样,G1从总体上基于标记一整理算法,将整个Java堆划分为多个大小相等的独立区域(Region),这种算法可以在运行过程当中不产生内存碎片
四、可预测的停顿:下降停顿时间是G1和CMS共同目标,可是G1追求低停顿外,还能创建可预测的停顿时间模型,能让使用者明确指定一个长度为M毫秒的时间片断内,消耗在垃圾收集器上的时间不得超过N毫秒。
eg:经过XX:MaxGCPauseMillis =500能够设置full gc 稳定在500ms之内
ps3:oracle一些1.9 10 11 12的特性都有以补丁的方式落到1.8。因此1.8仍是比较安全实用的