1. 背景

目前G1垃圾回收器无法及时的将Java堆内存返回给操作系统。G1仅仅当full GC或并发周期时才会返回内存。通常的,除非在外部强制的执行,G1在很多情况下不会返回堆内存给操作系统。

在云计算大行其道的计算的今天,很多部署环境是按资源支付的,这种行为特别不利。即使是JVM由于不活跃而仅仅使用分配的内存资源的一小部分,G1也将保留所有Java堆。这导致客户始终为没有使用的资源付费,云服务商也无法充分利用其硬件。

因此,希望垃圾回收器能够检测到Java堆的利用率不足,并在此情况下,自动减少堆使用量。

目前,Shenandoah(JEP - 189)和OpenJ9(IBM J9开源版)的GenCon收集器已经提供了类似的功能。

在Bruno使用原型进行的测试表明,此解决方案可以减少85%的内存使用率。

2. 快速返回内存的机制

为了实现尽快向操作系统返回堆内存的目标,G1将在JVM不活跃期间定期的尝试触发并发周期以确定整体Java堆的使用情况,这将会导致G1自动将Java堆的未使用部分返回给操作系统。

G1通过下面两个参数来决定是否触发定期垃圾回收:

  • G1PeriodicGCInterval
    自上一次垃圾收集暂停以来已经过了超过n毫秒,并且此时没有正在进行的并发周期。值为零表示禁用快速回收内存的定期垃圾收集。

  • G1PeriodicGCSystemLoadThreshold
    调用getloadavg()返回平均一分钟JVM主机或容器的负载值小于G1PeriodicGCSystemLoadThreshold。值为0则忽略此条件。

如果不满足以上条件中的任何一个,则不执行定期垃圾收集。G1PeriodicGCInterval毫秒后,再重新判断只发执行定期垃圾收集G1PeriodicGCInterval。
如果满足以上条件,触发full GC或者concurrent GC(如果开启G1PeriodicGCInvokesConcurrent),GC之后Java heap size会被重写调整,然后多余的内存将会归还给操作系统。

3. 如何启动定期垃圾收集

-Xlog:gc:…/logs/gc.log
-XX:G1PeriodicGCInterval=5000
-XX:G1PeriodicGCSystemLoadThreshold=0

从如下的gc日志我们可以看出,G1PeriodicGCInterval=5000 ms时,G1每隔5000毫秒触发定期垃圾收集,并返回未使用的堆内存给操作系统。

[0.064s][info][gc] Using G1
[0.221s][info][gc] Periodic GC enabled with interval 5000ms
[5.087s][info][gc] GC(0) Pause Young (Concurrent Start) (G1 Periodic Collection) 1M->1M(130M) 19.502ms
[5.087s][info][gc] GC(1) Concurrent Cycle
[5.094s][info][gc] GC(1) Pause Remark 1M->1M(10M) 1.518ms
[5.095s][info][gc] GC(1) Pause Cleanup 1M->1M(10M) 0.059ms
[5.096s][info][gc] GC(1) Concurrent Cycle 8.830ms
[10.254s][info][gc] GC(2) Pause Young (Concurrent Start) (G1 Periodic Collection) 1M->1M(10M) 15.772ms
[10.254s][info][gc] GC(3) Concurrent Cycle
[10.257s][info][gc] GC(3) Pause Remark 1M->1M(10M) 0.374ms
[10.257s][info][gc] GC(3) Pause Cleanup 1M->1M(10M) 0.066ms
[10.258s][info][gc] GC(3) Concurrent Cycle 3.096ms
[15.423s][info][gc] GC(4) Pause Young (Concurrent Start) (G1 Periodic Collection) 1M->1M(10M) 17.878ms
[15.423s][info][gc] GC(5) Concurrent Cycle
[15.425s][info][gc] GC(5) Pause Remark 1M->1M(10M) 0.350ms
[15.426s][info][gc] GC(5) Pause Cleanup 1M->1M(10M) 0.068ms
[15.426s][info][gc] GC(5) Concurrent Cycle 3.321ms

4. 相关代码

由于定期垃圾收集功能大量复用现有功能,代码量并不大,大部分代码都在f94c7929a44b commit中。

4.1 g1YoungRemSetSamplingThread.cpp

bool G1YoungRemSetSamplingThread::should_start_periodic_gc() {// 如果当前处于并发标记阶段,则退出// If we are currently in a concurrent mark we are going to uncommit memory soon.if (G1CollectedHeap::heap()->concurrent_mark()->cm_thread()->during_cycle()) {log_debug(gc, periodic)("Concurrent cycle in progress. Skipping.");return false;}// 检查距上次GC是否有足够时间uintx time_since_last_gc = (uintx)Universe::heap()->millis_since_last_gc();if ((time_since_last_gc < G1PeriodicGCInterval)) {log_debug(gc, periodic)("Last GC occurred " UINTX_FORMAT "ms before which is below threshold " UINTX_FORMAT "ms. Skipping.",time_since_last_gc, G1PeriodicGCInterval);return false;}// 检查系统负载是否低于阈值double recent_load;if ((G1PeriodicGCSystemLoadThreshold > 0.0f) &&(os::loadavg(&recent_load, 1) == -1 || recent_load > G1PeriodicGCSystemLoadThreshold)) {log_debug(gc, periodic)("Load %1.2f is higher than threshold %1.2f. Skipping.",recent_load, G1PeriodicGCSystemLoadThreshold);return false;}return true;
}

5. 引用

JEP 346: Promptly Return Unused Committed Memory from G1
https://openjdk.java.net/jeps/346

Java 12 JEP 346: Promptly Return Unused Committed Memory from G1相关推荐

  1. 今天,Java 12 正式发布了!

    自 2 月 7 日开始,Java 12 / JDK 12 就进入了 RC 阶段.按照发布周期,美国当地时间 3 月 19 日,也就是今天--Java 12 正式发布了! 全面学python的时代,作为 ...

  2. Java 12 / JDK 12 正式发布

    自 2 月 7 日开始,Java 12 / JDK 12 就进入了 RC 阶段.按照发布周期,美国当地时间 3 月 19 日,也就是今天--Java 12 正式发布了! Java 12 新特性 Jav ...

  3. Java 12 将于3月19日发布,8 个最终 JEP 一览

    开发四年只会写业务代码,分布式高并发都不会还做程序员?   JDK 12 已于2018年12月进入 Rampdown Phase One 阶段,这意味着该版本所有新的功能特性被冻结,不会再加入更多的 ...

  4. 今天,Java 12 正式发布了! 你在用哪个版本?

    自 2 月 7 日开始,Java 12 / JDK 12 就进入了 RC 阶段.按照发布周期,美国当地时间 3 月 19 日,也就是今天--Java 12 正式发布了! Java 12 新特性 Jav ...

  5. java 12_Java 12在哪下载 Java 12下载地址分享

    Java 12在哪下载?Java 12于2019年3月20日正式发布,于上一个版本不同,Java 12是一个短期支持版本,但是Java 12并不是一个小版本,依然为各位带来了一些重大新功能,想要使用J ...

  6. Java 12 要来了!

    近几个月,Java SE 即将收费的消息引发开发者内心的不安,不少人纷纷表示是时候弃 Java 而转战 Kotlin 战场,同时也有部分程序员仍静观其变.不过根据最新的消息,Java 12 即将于今年 ...

  7. Java 12正式发布,新特性解读!

    Java 12 如约而至,除了那些值得关注的特性,你也应该思考下 Java 的未来. 在 Java 9 之前,当一个版本被宣布为首选版本,存在一个"培育"(bedded-in)新 ...

  8. Java 12新功能完整指南

    六个月飞得如此之快,是时候再次仔细研究一下即将发布的新JDK版本. 让我们满足Java 12及其向开发人员介绍的功能. 自甲骨文推出其6个月加速发布节奏以来已经有一段时间了,要跟上每个版本及其添加到表 ...

  9. java 12 、13、14、15新特性汇总

    java 12 Switch 表达式 使用Java 12,switch不仅可以作为语句也可以作为表达式. 无论作为语句或者作为表达式,switch都可以使用传统/简化的作用域和控制流行为. 这将有助于 ...

最新文章

  1. 如何才能知道一个导师的人品?
  2. Linux Socket学习(十三)
  3. Redis Labs再次修改许可,没用几个月的Commons Clause或被删除
  4. 性能为MySQL 10倍!阿里云推出云原生数据仓库AnalyticDB基础版
  5. (王道408考研操作系统)第二章进程管理-第三节5:用信号量实现进程互斥、同步和前驱关系
  6. 合并模块和安装文件的区别
  7. 一键环境安装包无法修改网站目录提示.user.ini权限问题解决方法
  8. 【Arduino】颜色识别的智能搬运机器人设计
  9. JAVA事务@Transactional之propagation
  10. 服务器主机是什么系统版本,服务器主机是什么系统
  11. CRISPR最新:新CRISPR技术靶向更复杂的人类基因组代码
  12. 腾讯云后端面试15问(6年工作经验)
  13. 数字逻辑电路设计(实验测试题)
  14. 推荐几个网站 - (可视化、博客、社区、学习网站)
  15. 从豆瓣看《长安十二时辰》如何成为爆款IP?
  16. ORACLE函数库大全
  17. 大神偷偷收藏的7个自学网站,质量高且免费,请低调使用
  18. 基于单片机c语言的豆浆机,基于单片机的全自动豆浆机控制系统设计.doc
  19. httpclient-Connection pool shut down 问题排查
  20. 时隔多年我又再一次体验了一把跟大神聊天的感觉

热门文章

  1. MYSQL日期 字符串 时间戳互转--https://www.cnblogs.com/jhy-ocean/p/5560857.html
  2. 学习 PixiJS — 视觉效果
  3. 免费ssl证书申请以及nginx配置https访问攻略
  4. 大数据统计:发布近期网络辟谣TOP10,看看你信过几条?
  5. 《春天的二十二个夜晚》
  6. Spring Cloud Stream消息中间件通过RabbitMQ实现消息推送
  7. kafka消息确认ack_什么是确认(ACK)? ACK代表什么?
  8. 工业互联网+危化安全生产数字化综合管理云平台
  9. javascript字符串比较大小
  10. cisco实现ACL配置