首页 > 编程语言 >Java性能调优System的gc垃圾回收方法

Java性能调优System的gc垃圾回收方法

时间:2022-12-14 10:06:45浏览次数:57  
标签:调用 Java System 应用程序 调优 GC JVM gc

java性能调优System的gc垃圾回收方法

java性能调优System的gc垃圾回收方法示例解

一、什么是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等。这些工具将生成丰富的垃圾收集分析报告。


Java性能调优System的gc垃圾回收方法_JVM

上图摘自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,JVM,gc
From: https://blog.51cto.com/u_15733182/5935453

相关文章

  • Java中ArrayList同步的2种方法分享
    Java中ArrayList同步的2种方法分享​​arrayList​​ 的实现是默认不同步的。这意味着如果一个线程在结构上修改它并且多个线程同时访问它,它必须在外部同步。结构修改意味......
  • 利用CSS、JavaScript及Ajax实现图片预加载的三大方法
    预加载图片是提高用户体验的一个很好方法。图片预先加载到浏览器中,访问者便可顺利地在你的网站上冲浪,并享受到极快的加载速度。这对图片画廊及图片占据很大比例的网站来说......
  • 24_Java网络编程
    Java_网络编程一、网络编程入门友情提示使用网络编程代码时,注意连接网络的变化(IP地址会变),可能不注意的话导致无法正确运行stocket:套接字1、网络编程......
  • 新装Eclipse运行Java程序报错Exception in thread "main" java.lang.UnsupportedClass
    错误现象:  Exceptioninthread"main"java.lang.UnsupportedClassVersionError:views/LoginFramehasbeencompiledbyamorerecentversionoftheJavaRunt......
  • 如何使用 System.Text.Json 序列化 DateTimeOffset 为 Unix 时间戳
    在.NET中,日期和时间通常使用DateTime或DateTimeOffset来表示。这两种数据类型都可以表示日期和时间,但它们之间有一些明显的区别。DateTime是不带时区信息的,而DateT......
  • Java Object转实体(自用)
    JavaObject转实体一、遇到的问题在从RedisHash根据一些条件(类似*|0)查询对应的HashValue时,发现在Java里获取RedisHash中的Value其实是字符串的形式。我尝试使用了fa......
  • Java复习笔记-抽象、接口、内部类、枚举
    1抽象abstractclass类名{//方法(实现的,抽象方法)//属性}1.1抽象类的细节1).抽象类不能被实例化2).可以有不是抽象的......
  • java和ssm开发的经销系统
    简介Ssm服装经销系统,主要分为6个角色:管理员、资料员、采购员、仓库员、售卖员、财务。采购员进行采购入库;仓库员进行采购入库、退货入库、提货出库、折损出库等库存管理;售卖......
  • java和vue车辆管理系统车管所系统
    简介车辆管理系统车管所系统,管理员添加车主信息,车主提交自己的车辆信息,管理员审核车辆,对车辆行进年检,统计,记录车辆违规信息。车主可以查看自己的车辆信息、投诉、查看自己的......
  • java和vue的大学生奖学金助学金系统奖学金系统助学金系统
    简介大学生奖学金助学金系统。学生申请自己需要的奖助学金,上传证明材料。该学院的辅导员可以下载学生的证明材料以及根据学生的综合成绩来审核是否通过,若不通过请输入不通过......