JVM之GC
JVM之GC
垃圾回收算法
讲垃圾回收算法之前,先简单说一下两个算法依据
- 引用计数算法:
java在运行时,一个对象如果有被引用则对象实例+1,引用失效-1,垃圾回收时,找到引用为0的回收即可,这种算法缺点比较明显,当对象互相引用时,则无法回收到。JVM没有采用该算法
2. 可达性分析算法
相对于引用计数算法,有根节点的概念,通过根节点的对象引用链,来找到不需要回收的对象。最终无法到达的对象即为需要回收的对象。跟节点如何选取:类加载器、Thread、虚拟机栈本地变量、static成员、常量引用、本地方法栈等等都是root节点的选择对象
标记清除
将需要回收的对象进行标记,最后进行清除
特点:效率一般且会产生碎片
标记整理
和标记清除类似,先标记需要回收的对象,不同之处在于清除对象后,会将现有的对象进行整理来解决碎片化的问题。但是比较耗时
复制算法
复制算法会将内存按容量分为两块区域,每次只使用其中一块。回收垃圾时,将保留的对象直接复制到另外一块区域,同时直接清除本区域的对象。
特点:简单高效、空间利用率低
分带垃圾回收
分带垃圾回收是将内存分类,Young区和old区,每个分区使用不同的回收算法。来高效的利用回收算法的优缺点。JVM中也是使用了改逻辑来处理的。
Young区:复制算法
Old区:标记清除或标记整理
垃圾收集器
串行收集器Serial
开启参数:-XX:+UseSerialGC
串行收集器属于一种传统的收集器。内存很小时会使用,比如一些嵌入式的程序中会使用该收集器。
特点是:简单高效,效率高。但是必须暂停其他所有的工作线程
并行收集器Parallel
开启参数:-XX:+UseParallelGC,-XX:+UseParallelOldGC
service模式默认的收集器
并发收集器Concurrent
CMS:-XX:+UseConcMarkSweepGC -XX:+UseParNewGC
G1:-XX:+UseG1GC
JVM常用的收集器和优化点
以JDK8为例,可以查看官网:HotSpot虚拟机垃圾收集优化指南
并行收集器
并行收集器(也称为吞吐量收集器)是相对于串行收集器而言的,区别在于收集垃圾时,使用的多线程来收集。收集时也是需要暂停应用程序的。
设置线程数 -XX:ParallelGCThreads=<N>
核心数N小于8时等于N,大于8时为5/8。 也可以用上诉方式调优
在并行收集器中使用了一种自动调整的方法,JDK推荐使用以下3个参数来帮助收集器来调整性能。 以下排名有先后顺序
- 最大垃圾回收暂停时间
-XX:MaxGCPauseMillis=<N>
- 吞吐量
-XX:GCTimeRatio=<N>
比如配置99,则表示收集时间 1/1+N 为1% - 内存占用 -Xmx
通过这三个参数,收集器会自动优化程序,达到以上的要求。
Generation Size Adjustment
同时我们还可以调整分区的动态适应参数来帮助其更好的优化
-XX:YoungGenerationSizeIncrement=<Y>
young generation增长比率 默认为20-XX:TenuredGenerationSizeIncrement=<T>
tenured generation增长比率 默认为20-XX:AdaptiveSizeDecrementScaleFactor=<D>
缩小因子,如果增长比率是X,那么缩小比率就是 X / D, 默认为4,也就是5%
如果collector决定在启动的时候就增长generation,那么会在原增长比率上有一个增加量,这个增加量会随着gc次数越来越低,这个主要是为了提高启动的性能。缩小时没有增加量。
如果最大pause time的目标没有达成,那么会一次自会缩小一个generation。如果两个generation都达不到目标,那么pause time较长的那个会先被缩小
如果throughput的目标没有达到,那么两个generation区域都会被增加。然后按照比例扩展,比如young generation的gc时间占到总gc时间的25%,而增长比率是20%,那么实际会增长5%。
CMS
CMS适合在响应时间要求比较的服务器上使用,
G1
原文作者: duteliang
原文链接: http://yoursite.com/2019/03/15/jvm/JVM之GC/
版权声明: 转载请注明出处(必须保留原文作者署名原文链接)