zoukankan      html  css  js  c++  java
  • java程序性能优化读书笔记-垃圾回收

    衡量系统性能的点
    • 执行速度:即响应时间
    • 内存分配:内存分配是否合理,是否过多消耗内存或者存在内存泄露
    • 启动时间:程序从启动到正常处理业务需要的时间
    • 负载承受能力:当系统压力上升,系统执行速度和响应时间上升曲线是否平缓

    系统调优层次
    • 系统设计调优
    • 代码调优
    • jvm调优
    • 数据库调优
    • 操作系统调优

    垃圾回收基础

    垃圾回收算法:

    • 引用计数法:每个对象都有一个引用计数器,当被一个对象引用的时候计数器+1,当引用失效的时候计数器-1,当计数器为0的时候就可以被回收掉。这种算法的缺陷是,不能解决循环引用的问题,当AB相互引用的时候,各自的引用计数器都为1,但是他们都没有被第三个对象所引用,所以是可以被回收掉的。由于由这种缺陷,引用计数法不适合JVM的垃圾回收。

    • 标记-清除算法:标记清除法是现代垃圾回收算法思想的基础。从根节点开始,通过标记根节点开始所有可达的对象,标记完成后,对未标记的对象进行清除。这种算法的缺点是,清除后会出现不连续的内存区域。不连续的内存空间效率比连续的内存空间要低。

    • 复制算法:把内存区域分成2块。一块是正在使用的,一块是没有在使用的。当进行垃圾回收的时候,把存活的对象从正在使用的区域复制到非正在使用的区域,然后清除正在使用区域的所有对象,交换2个内存的角色完成垃圾回收。这样可用区域的内存就连续了。如果垃圾对象多余存活对象,这种方式效果就比较好。

      java新生代垃圾串行回收器使用了复制算法的思想。

    • 标记压缩算法:适合老年代回收算法。在标记清除法的基础上做了优化。当需要回收的对象比较少的时候,这种算法比较高效。标记完后,把存活的对象压缩到内存的一端,然后把垃圾对象清理,这样就避免了不连续区域。

    • 增量算法:对于大部分垃圾回收算法,垃圾回收的时候会stop the world,所有应用的线程都会挂起,导致停顿。增加的话,是分区域垃圾回收,减少垃圾回收的范围,然后再间歇运行下应用程序。

    • 分代:将内存区域根据对象特点分成几块,不同的块使用不同的垃圾回收算法。在Hot Spot虚拟机中,所有新建的对象都放到新生代,当一个对象经过几次回收仍然存活就放入老年代

    内存区域 使用的算法
    新生代 复制算法
    老年代 标记压缩算法

    JVM调优常见案例
    • 大对象进入老年代:新生的大对象如果放在新生带可能会扰乱新生代的内存回收,因为新生代如果被大对象挤满了,新产生的对象都会被挤过去老年代, -XX:PretenureSizeThreshold 设置大对象直接进入老年代的阈值。 如果进入了老年代,又比较短命的话,标记压缩算法又会很不利,所以如果短命的大对象太多,对垃圾回收是一种灾难。

    • 设置进入老年代的年龄:新生代进入老年代和年龄有关。新对象会放在eden区,如果经过一次回收仍然存活,则被放入survivior区,对象年龄增加1。如果年龄达到的阈值就会被挪到老年代。-XX:MaxTenuringThreshold 设置最大年龄。

    • 稳定与震荡的堆大小: 稳定的堆大小会减少GC的次数,因此有的人会设置最小堆内存和最大堆内存成一样的值。但是GC堆大的话也会影响单次GC的时间。因此出了Xmx和Xms外还提供了以下参数。当Xmx和Xms一样的时候以下参数无效。

    参数 作用
    -XX:MinHeapFreeRatio:40 堆空间最小空闲比例,默认是40。当空闲的小于40%的时候,会扩大堆空间,确保程序空闲的时候震荡不会太大。
    -XX:MaxHeapFreeRatio:70 堆空间最大空闲比例,默认是70。当空闲的空间大于70%的时候,会压缩堆空间。

    实用案例

    • 吞吐量优先案例(32核,4G)
    启动参数 参数解析
    -Xmx3800m -Xms3800m 减少堆震荡和频繁GC。吞吐量大,内存一般都会维持在较高水平
    -Xss128k 减少线程栈大小,剩余的系统内存支持更多的线程。
    -Xmn2g 设置新生代大小
    -XX:UseParallelGC 新生代使用并行回收器
    -XX:ParallelGCThreads=20 设置垃圾回收线程总数
    -XX:UseParallelOldGC 老年代也使用并行回收器
    • 使用大叶案例:在Solaris系统中,jvm支持大页使用 -XX:LargePageSizeInBytes=256m

    • 降低停顿案例

    启动参数 参数解析
    -XX:ParallelGCThreads=20 设置垃圾回收线程总数
    -XX:UseParallelGC 新生代使用并行回收器
    -XX:UseConcMarkSweepGC 老年代使用CMS收集器降低停顿
    -XX:SurvivorRatio=8 eden区:survivor区 = 8:1 稍大的survivor区,可以提高在新生代回收声明周期较短的对象的可能性,避免进入老年代
    -XX:TargetSurvivor=90 设置survivor的可使用率为90%,默认是50%,提高了survivor区的实用率
    -XX:MaxTenuringThreshold=31 设置年轻代进入老年代的年龄,默认是15,这里设置成31,尽可能地将对象保存在新生代
  • 相关阅读:
    win10 redis安装教程
    tomcat 最大并发连接数设置
    LeetCode 82 ——删除排序链表中的重复元素 II
    LeetCode 83 —— 删除排序链表中的重复元素
    LeetCode 61——旋转链表
    LeetCode 24——两两交换链表中的节点
    C++ 学习笔记之——文件操作和文件流
    LeetCode 4——两个排序数组中的中位数
    z 变换
    冲激串采样
  • 原文地址:https://www.cnblogs.com/still-windows7/p/jvm.html
Copyright © 2011-2022 走看看