• Java性能权威指南读书笔记--之二


    新生代填满时,垃圾收集器会暂停所有的应用线程,回收新生代空间。这种操作被称为Minor GC。
    老年代被填满时,垃圾收集器会暂停所有应用线程,对其进行回收,接着对堆空间进行整理。这个过程被称为Full GC。
    最主流的四个垃圾收集器分别是:Serial收集器、Throughput(或者Parallel)收集器、Concurrent(CMS、G1)垃圾收集器。Concurrent垃圾收集器可以通过复杂的计算,可以在应用线程运行的同时找出不再使用的对象。
    使用CMS或G1收集器时,应用程序精力的停顿会更少,所带来的代价是消耗更多的CPU。
    评估垃圾收集器时,应考虑以下几点:

    • 如果要尽可能地缩短相应时间,那么选择使用Concurrent收集器更合适
    • 如果平均相应时间比最大响应时间更重要,那么应该使用Parallel收集器
    • 使用Concurrent收集器来避免长时间停顿时间也有其代价,这会消耗额外的CPU
      • 如果CPU足够强劲,使用Concurrent收集器避免发生Full GC可以让任务运行得更快
      • 如果CPU资源有限,那么Concurrent收集器额外的CPU消耗会使批量任务消耗更多的时间

    GC算法

    1. Serial垃圾收集器
      使用单线程清理堆的内容。进行Full GC时,它还会对老年代空间的对象进行压缩整理。通过-XX:+UseSeralGC标志可以启用Serial收集器
    2. Parallel收集器
      Parallel收集器可以使用多线程对堆空间进行回收。在MinorGC和FullGC时会暂停所有的应用线程,同事在FullGC过程中会对老年代空间进行压缩整理。通过-XX:+UseParallelOldGC标志可以开启这个功能。
    3. CMS收集器
      CMS收集器在MinorGC时会暂停所有的应用线程,并以多线程的方式进行垃圾回收(-XX:UseParNewGC)。CMS收集器在进行FullGC时不再暂停应用线程,而是使用若干个后台线程定期地对老年代空间进行扫描, 及时回收其中不在使用的对象,并且后台线程不在进行任何压缩整理的工作。如果堆的碎片化过于严重CMS收集器会暂停所有应用线程,使用单线程回收、整理老年代空间(-XX:UseConcMarkSweepGC)。
    4. G1垃圾收集器
      G1收集算法将堆划分为若干个区域,新生代的垃圾收集仍然采用暂停所有应用线程的方式,将存货对象移动到老年代或者Servivor空间。老年代的垃圾收集工作由后台线程完成,由于老年代被划分到不同的区域,G1收集器通过将对象从一个区域复制到另一个区域,完成对象的清理工作,同时在进行了堆的压缩整理(-XX:+UseG1GC)。

    选择GC算法

    如果有额外的CPU处理能力,那么使用Concurrent收集器将极大地提升应用程序的性能。
    通常情况下,parallel收集器的平均响应时间比Concurrent收集器要差,但是在90%响应时间或者99%响应时间这几项指标上,parallel收集器比Concurrent收集器要好一些。
    使用parallel收集器会超负荷地进行大量Full GC时,切换到Concurrent收集器通常能获得更低的响应时间。
    一般情况下,堆空间小于4GB时,CMS收集器的性能比G1收集器好。
    G1的设计使得它能够在不同的分区处理堆,因此它的扩展性更好,比CMS更易于处理超大堆的情况。

    调整堆的大小

    通常情况下,对于普通的操作系统,应该预留至少1G的内存空间。
    堆的大小由2个参数值控制:分别是初始值(通过 -Xms N设置)和最大值(通过-Xms N设置)。
    如果确切地了解应用程序需要多大的堆,那么可以将堆的初始值和最大值直接设置成对应的数据(譬如:-Xms4096m -Xmx4096m)。这种设置能稍微提高GC的运行效率,因为它不再需要估算堆是否需要调整大小了。
    任何事情都有两面性,如果新生代分配得比较大,垃圾收集发生的频率就比较低,从新生代晋升到老年代的对象也更少,但是老年代就相对比较小,比较容易被填满,会更频繁的触发Full GC。
    所有用于调整代空间的命令行标志调整的都是新生代空间;新生代空间剩下的所有空间都被老年代占用。
    -XX:NewRatio=N
    设置新生代与老年代的空间占用比率
    -XX:NewSize=N
    设置新生代空间的初始大小
    -XX:MaxNewSize=N
    设置新生代空间的最大大小
    -XmnN
    将NewSize和MaxNewSize设定为同一个值的快捷方法
    最初的新生代的大小由NewRatio的决定,默认值为2.
    Initial Young Get Size = Initial Heap Size/(1 + NewRatio)
    新生代空间的大小是初始堆大小的33%
    多线程的垃圾收集器算法是由-XX:ParallelGCThreads=N参数控制
    总的垃圾收集器线程数 = 8 + (N - 8)* 5/8
    有时候垃圾收集线程需要调整,例如在128C的机器上使用一个1G的堆,那么会启动83个线程,明显就偏大了;又如在16C的机器同时运行4个JVM实例,那么每个JVM会启动13个垃圾收集器线程,总共会有52个垃圾收集器线程,这样会导致大量冲突,那么将每个JVM的垃圾收集器限制为4个是一个比较合理的平衡。

    垃圾回收工具

    -XX:+PrintGCDetails
    创建详细的GC日志
    -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps
    GC时发生的日期,可以配合上面的参数使用
    -Xloggc:filename,可以配合上面的参数使用
    修改GC日志输出到某个文件
    -XX:+UseGCLogFileRotation
    -XX:NumberOfGCLogFiles=N
    -XX:GCLogFileSize=N
    可以控制日志文件的循环。NumberOfGCLogFiles产生日志的个数,GCLogFileSize日志的大小

  • 相关阅读:
    .Net转Java自学之路—SpringMVC框架篇九(拦截器)
    .Net转Java自学之路—SpringMVC框架篇八(RESTful支持)
    移动端高清适配、布局开发解决方案
    Webpack+Gulp+React+ES6开发
    gulp使用gulp-file-include将header/footer引入页面
    git在window与linux的换行符问题
    文件(图片)上传组件
    ie8、9跨域上传文件(图片)
    移动端rem布局背景图片使用以及sprite雪碧图
    iOS/Android 浏览器(h5)及微信中唤起本地APP
  • 原文地址:https://www.cnblogs.com/luozhiyun/p/10612081.html
Copyright © 2020-2023  润新知