新生代填满时,垃圾收集器会暂停所有的应用线程,回收新生代空间。这种操作被称为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日志的大小

Java性能权威指南读书笔记--之二的更多相关文章

  1. Java性能权威指南读书笔记--之一

    JIT(即时编译) 解释型代码:程序可移植,相同的代码在任何有适当解释器的机器上,都能运行,但是速度慢. 编译型代码:速度快,电视不同CPU平台的代码无法兼容. java则是使用java的编译器先将其 ...

  2. 经典的性能优化最佳实践 web性能权威指南 读书笔记

    web性能权威指南 page 203 经典的性能优化最佳实践 无论什么网络,也不管所用网络协议是什么版本,所有应用都应该致力于消除或减 少不必要的网络延迟,将需要传输的数据压缩至最少.这两条标准是经典 ...

  3. Java性能优化权威指南-读书笔记(二)-JVM性能调优-概述

    概述:JVM性能调优没有一个非常固定的设置,比如堆大小设置多少,老年代设置多少.而是要根据实际的应用程序的系统需求,实际的活跃内存等确定.正文: JVM调优工作流程 整个调优过程是不断重复的一个迭代, ...

  4. 《Java性能权威指南》笔记----JIT编译器

    概览 编译型语言(C++,Fortran等):运行程序前,需要用编译器将代码静态编译成CPU可执行的汇编码.汇编码针对特定的CPU. 优点:只需编译一次,且有足够的程序信息来优化汇编码.执行速度快: ...

  5. 《Java性能权威指南》笔记----Java性能调优工具

    OS 1.CPU 用户态时间(us):cpu执行应用代码所占时间的百分比. 内核态时间(sy):cpu执行内核代码所占时间的百分比,系统态时间与应用相关. 空闲时间(id):cpu空闲时间百分比.空闲 ...

  6. JS权威指南读书笔记(二)

    第四章 表达式和运算符 1 new调用构造函数的过程     a 创建一个新的空对象     b 设置空对象的_proto_指向构造函数原型prototype     c 将这个新对象当做this的值 ...

  7. 《Java编程思想》读书笔记(二)

    三年之前就买了<Java编程思想>这本书,但是到现在为止都还没有好好看过这本书,这次希望能够坚持通读完整本书并整理好自己的读书笔记,上一篇文章是记录的第一章到第十章的内容,这一次记录的是第 ...

  8. HTTP权威指南读书笔记

    HTTP权威指南笔记 读书有两种境界,第一种境界是将书读薄,另一种是读厚.本篇文章就是HTTP权威指南的读书笔记,算是读书的第一重境界,将厚书读薄.文章对HTTP的一些关键概念做了比较详细的概述,通读 ...

  9. css权威指南读书笔记

    今天翻手机,翻到了许久之前看css权威指南时的笔记,遂移到博客中来. 1.属性选择器p.one class名为one的p元素p[class][name] 含有class和name属性的p元素p[cla ...

随机推荐

  1. node.js中模块,require

    在php,C++中都有命名空间的概念,命名空间主要是用来解决引入文件存在函数,类,变量重名的问题,在node.js中,没有命名空间这么复杂的概念,在node中,有模块的概念,也就是将功能性的代码都放在 ...

  2. docker容器中使用pip有警告

    docker容器中使用pip有警告 /usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/util/ssl_.py:334: ...

  3. Effective Java - 静态方法与构造器

    目录 用静态工厂方法替代构造器? 静态工厂有名称 静态工厂不必重新创建一个对象 静态工厂可以返回任何子类型对象 静态工厂返回的类可以动态变化 静态工厂返回的类可以不存在 静态工厂方法的缺点 静态工厂方 ...

  4. JAVA增强for循环

    作用:简化数组和集合的遍历 格式:for(元素数据类型  变量 :数组或者集合) 例子: Map map=new HashMap; for(Object obj :map.keySet()){ Obj ...

  5. c# bool类型和int类型的互转

    项目过程中,会有model的一些属性字段为‘是’或‘否’ 数据库字段一半定义为int,值则是0或1 数据库model转实体类的时候,bool和int可以直接相互转换 false强转int 值就是0 t ...

  6. 音频算法speex中的aec分析以及解析

    算法原理: Speex的AEC是以NLMS(Normalized Least Mean Square)为基础,用MDF(multidelay block frequency domain)频域实现,最 ...

  7. Python Day_2

    入门任何一门编程语言,前面总是离不开变量,字符串这些概念,而且这些东西在往后的日子里,有着至关重要的存在.因为不管我们写什么程序,都要用到变量以及字符串. 变量 首先,我们的变量在定义的时候,是不需要 ...

  8. javascript高级笔记——内含事件,DOM,BOM等

    JavaScript高级笔记 1,DOM的简单学习 1.1,功能:用于控制HTML文档的内容: 1.2,获取页面标签对象:Element *document.getElementById(" ...

  9. UEditor 之初体验后记

    1.UEditor 基本介绍 1.1.关于 UEditor 1.2.UEditor 现状 2.UEditor 简单使用 2.1.将 UEditor 源码集成到项目中 2.2.让 UEditor 的 U ...

  10. 数据库触发器_trigger

    部门表_删除: USE [test] GO /****** Object: Trigger [dbo].[部门_Delete] Script Date: 2015/8/31 16:41:46 **** ...