一、什么是System.gc()?

System.gc()是用Java,C#和许多其他流行的高级编程语言提供的API。当它被调用时,它将尽最大努力从内存中清除垃圾(即未被引用的对象)。名词解释:GC,Garbage Collection,垃圾回收,下文会经常使用。

二、谁可以调用System.gc()?

System.gc() 可以从应用程序堆栈的各个部分调用:

  • 您自己开发的应用程序可以显式的调用 System.gc() 方法。
  • System.gc() 也可以由您的第三方库,框架触发。
  • 可以由外部工具(如VisualVM)通过使用JMX触发
  • 如果您的应用程序使用了RMI,RMI会定期调用 System.gc() 。

三、调用System.gc()有什么弊端?

当 System.gc() 或 Runtime.getRuntime().gc()API被调用时,将触发完整的GC事件。在GC完成之前,整个JVM将冻结(即正在运行的所有服务将被暂停),通常完整的GC需要很长时间才能完成。因此在不合适的时间运行GC,将导致不良的用户体验,甚至是崩溃。

JVM具有复杂的算法,该算法始终在后台运行,进行所有计算以及有关何时触发GC的计算。当您显式调用System.gc()调用时,所有这些计算都将被抛掉。

四、哪些场景适合显式调用System.gc()?

GC操作应该由JVM自行控制,在绝大部分的场景都不建议程序员手动写代码显式进行System.gc()操作,但是也不排除其中个别例外:在我们开发多个微服务时,每个服务都有多个备份节点。在非业务高峰时段,我们可以从微服务-负载均衡的节点池中取出其中一个JVM实例。然后通过该JVM上的JMX显式触发System.gc()调用,一旦GC事件完成并且从内存中清除了垃圾,将该JVM放回到微服务-负载均衡的节点池中。

当然这个过程需要很好的微服务管理及服务发布机制配合,这样既能保证JVM垃圾内存的有效清理,又不影响业务的正常运行。

五、如何检测您的应用程序正在进行System.gc()?

如第二小节所讲: System.gc() 可以从多个渠道进行的调用,而不仅仅是从您的应用程序源代码进行的调用。因此,搜索您的应用程序代码System.gc() 字符串,不足以知道 GC是否正在被调用。这就构成了一个挑战:如何检测应用程序是否正在进行垃圾回收?这就是GC日志派上用场的地方。

// java 8 启用GC日志:
// -XX:+PrintGCDetails -Xloggc:<gc-log-file-path> ,例如下面这行代码
-XX:+PrintGCDetails -Xloggc:/opt/tmp/myapp-gc.log // java 9 启用GC日志:-Xlog:gc*:file=<gc-log-file-path> ,例如下面这行代码
-Xlog:gc*:file=/opt/tmp/myapp-gc.log

建议始终在所有生产服务器中始终启用GC日志,因为它有助于您排除故障并优化应用程序性能。启用GC日志只会增加微不足道的开销。还可以将您的GC日志上传到垃圾收集日志分析器工具,例如GCeasy,HP JMeter等。这些工具将生成丰富的垃圾收集分析报告。

上图摘自GCeasy生成的报告。

六、如何禁止GC显式调用或调整调用GC的频率?

如果我们就是想避免程序员显式调用GC,避免不成熟的程序员在不合适时间调用GC,避免人为造成的GC崩溃,该怎么办?可以通过如下方法:

搜索和替换

在代码库中搜索 System.gc() 和Runtime.getRuntime().gc()。如果看到匹配项,则将其删除。但是这种方法无法避免第三方库、框架或通过外部源进行调用,那么参考第二种方法。

通过JVM参数强制禁止

通过传递JVM参数  -XX:+DisableExplicitGC来强制禁止显式调用。这种方式强制、有效,应用程序内的任何GC显式代码调用System.gc() 都将被禁止生效。JVM自身的GC策略不受此参数影响,只禁止人为的触发GC。

RMI

如果您的应用程序正在使用RMI,则可以控制GC调用的频率 。启动应用程序时,可以使用以下JVM参数配置该频率:

  • -Dsun.rmi.dgc.server.gcInterval=n
  • -Dsun.rmi.dgc.client.gcInterval=n

这些属性的默认值在

  • JDK 1.4.2和5.0是60000毫秒(即60秒)
  • JDK 6和更高版本是3600000毫秒(即60分钟)

如果您的应用主机内存资源非常富余,您可以将这些属性设置为很高的值,以便可以将GC带来的对应用程序的影响最小化。这也是应用程序性能优化的一种方式之一。

期待您的关注

java应用性能调优之详解System的gc垃圾回收方法的更多相关文章

  1. JVM性能调优监控工具详解

    现实企业级Java开发中,有时候我们会碰到下面这些问题: OutOfMemoryError,内存不足 内存泄露 线程死锁 锁争用(Lock Contention) Java进程消耗CPU过高 .... ...

  2. MySQL性能调优——索引详解与索引的优化

    --索引优化,可以说是数据库相关优化.理解尤其是查询优化中最常用的优化手段之一.所以,只有深入索引的实现原理.存储方式.不同索引间区别,才能设计或使用最优的索引,最大幅度的提升查询效率! 一.BTre ...

  3. 面试题:MySQL性能调优——索引详解与索引的优化 没用

    ——索引优化,可以说是数据库相关优化.理解尤其是查询优化中最常用的优化手段之一.所以,只有深入索引的实现原理.存储方式.不同索引间区别,才能设计或使用最优的索引,最大幅度的提升查询效率! 一.BTre ...

  4. [转载]Java 应用性能调优实践

    Java 应用性能调优实践 Java 应用性能优化是一个老生常谈的话题,笔者根据个人经验,将 Java 性能优化分为 4 个层级:应用层.数据库层.框架层.JVM 层.通过介绍 Java 性能诊断工具 ...

  5. JVM性能调优的6大步骤,及关键调优参数详解

    JVM性能调优方法和步骤1.监控GC的状态2.生成堆的dump文件3.分析dump文件4.分析结果,判断是否需要优化5.调整GC类型和内存分配6.不断分析和调整JVM调优参数参考 对JVM内存的系统级 ...

  6. 直通BAT必考题系列:JVM性能调优的6大步骤,及关键调优参数详解

    JVM内存调优 对JVM内存的系统级的调优主要的目的是减少GC的频率和Full GC的次数. 1.Full GC 会对整个堆进行整理,包括Young.Tenured和Perm.Full GC因为需要对 ...

  7. Java 应用性能调优实践

    Java 应用性能优化是一个老生常谈的话题,笔者根据个人经验,将 Java 性能优化分为 4 个层级:应用层.数据库层.框架层.JVM 层.通过介绍 Java 性能诊断工具和思路,给出搜狗商业平台的性 ...

  8. Java虚拟机性能调优相关

    一.JVM内存模型及垃圾收集算法 1.根据Java虚拟机规范,JVM将内存划分为:New(年轻代)Tenured(年老代)永久代(Perm) 其中New和Tenured属于堆内存,堆内存会从JVM启动 ...

  9. java开发性能调优

    从总体上来看,对于大型网站,比如门户网站,在面对大量用户访问.高并发请求方面,基本的解决方案集中在这样几个环节:1.首先需要解决网络带宽和Web请求的高并发,需要合理的加大服务器和带宽的投入,并且需要 ...

随机推荐

  1. 转:python2.x 和 python3.x的区别

    注:本文的原文地址为Key differences between Python 2.7.x and Python 3.x 许多 Python 初学者想知道他们应该从 Python 的哪个版本开始学习 ...

  2. python编程基础之十四

    列表的增加元素 l1 = [10, 20, 30] l1.append(40)  # 末尾追加一个值为40的元素 l1.extend([50, 60])  # 末尾追加一系列元素,extend + 可 ...

  3. 【TencentOS tiny】深度源码分析(7)——事件

    引言 大家在裸机编程中很可能经常用到flag这种变量,用来标志一下某个事件的发生,然后在循环中判断这些标志是否发生,如果是等待多个事件的话,还可能会if((xxx_flag)&&(xx ...

  4. Airport Express UVA - 11374

    In a small city called Iokh, a train service, Airport-Express, takes residents to the airport more q ...

  5. Ubuntu16.04换源

    换成国内最快的阿里云源 第一步:备份原来的源文件 cd /etc/apt/ 然后会显示下面的源文件sources.list 输入命令 sudo cp sources.list sources.list ...

  6. OD 逆向工具常用快捷键

    F2:设置断点,只要在光标定位的位置(上图中灰色条)按F2键即可,再按一次F2键则会删除断点. F8:单步步过.每按一次这个键执行一条反汇编窗口中的一条指令,遇到 CALL 等子程序不进入其代码. F ...

  7. windows系统安全日志取证工具

    0x01 关于日志 Windows安全事件日志中详细记录了是谁在什么时候通过什么手段登录到系统或者注销了登录,通过分析该日志可以详细了解服务器的安全情况以及必要时的取证工作. 0x02 查看日志 传统 ...

  8. 玩转OneNET物联网平台之简介

    授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...

  9. 使用eclipse在tomcat中设置项目启动的虚拟路径

    很多时候我们在启动项目的时候都会在浏览器输入"localhost:+端口号+项目名称" 其实tomcat是可以省去这种麻烦的,通过设置项目的虚拟路径就可访问项目了 第一步 选择ec ...

  10. 在idea中添加try/catch的快捷键

    在idea中添加try/catch的快捷键ctrl+alt+t选中想被try/catch包围的语句,同时按下ctrl+alt+t,出现下图