大小对于软件至关重要。 很明显,与大型整体方法相比,在微服务体系结构中使用小型组件具有更多优势。 最新的Java版本的Jigsaw可帮助分解旧应用程序或从头开始构建新的云原生应用程序。

这种方法减少了磁盘空间,构建时间和启动时间。 但是,它对RAM使用管理没有足够的帮助。 众所周知,Java在许多情况下会消耗大量内存。 同时,许多人还没有注意到Java在内存使用方面已经变得更加灵活,并且提供了满足微服务需求的功能。 在本文中,我们将分享我们的经验,如何在Java进程中调整RAM的使用以使其更具弹性,并获得更快的扩展和更低的总体拥有成本(TCO)的好处。

缩放有三个选项:垂直,水平以及两者的组合。 为了最大化结果,首先您需要以最佳方式设置垂直缩放。 然后,当您的项目水平增长时,单个容器内的预配置资源消耗将被复制到每个实例,效率将成比例地增长。

如果配置正确,则垂直缩放可完美适用于微服务和整体,可根据容器内的当前负载优化内存和CPU使用率。 选定的垃圾收集器是主要的基础砖之一,其设置会影响整个项目。

OpenJDK有五种广泛使用的垃圾收集器解决方案:

  • G1
  • 平行
  • ConcMarkSweep(CMS)
  • 序列号
  • 雪兰多

让我们看看它们在缩放方面的表现以及可以应用哪些设置来改善结果。

为了进行测试,我们将使用一个示例Java应用程序来帮助跟踪JVM垂直缩放结果: https : //github.com/jelastic/java-vertical-scaling-test

将为每个GC测试启动以下JVM启动选项:

java -XX:+Use[gc_name]GC -Xmx2g -Xms32m -jar app.jar [sleep]

哪里:

  • [gc_name]将替换为特定的垃圾收集器类型
  • Xms是扩展步骤(本例中为32 MB)
  • Xmx是最大缩放限制(本例中为2 GB)
  • [sleep]是内存加载周期之间的间隔(以毫秒为单位),默认为10

目前,为了完全释放未使用的资源,需要调用Full GC。 它可以通过各种选项轻松启动:

  • jcmd <pid> GC.run –执行外部调用
  • System.gc() – 源代码内
  • jvisualvm –通过出色的VisualVM故障排除工具手动进行
  • -javaagent:agent.jar –可插入的常用方法。 Github repo Java Memory Agent上提供了开源自动化附件。

可以在输出日志中跟踪内存使用情况,或使用VisualVM进行更深入的查看。

G1垃圾收集器

对于Java生态系统来说,好消息是,从JDK 9开始,默认情况下启用了现代收缩的G1垃圾收集器。 如果使用较低版本的JDK,则可以使用-XX:+UseG1GC参数启用G1。

G1的主要优势之一是能够压缩可用的内存空间,而无需花费较长的暂停时间和不提交未使用的堆的能力。 我们发现,对于在OpenJDK或HotSpot JDK上运行的Java应用程序进行垂直扩展,此GC是最佳选择。

为了更好地了解JVM在不同的内存压力级别下的行为,我们将运行以下三种情况:1)快速,2)中速和3)内存使用量增长缓慢。 这样,我们可以检查G1人机工程学的智能程度以及GC如何处理不同的内存使用动态。

内存使用量快速增长

java -XX:+UseG1GC -Xmx2g -Xms32m -jar app.jar 0

内存在25秒内从32 MiB增长到1 GiB。

G1内存使用量快速增长

如果内存使用量增长非常快,则根据其内部自适应优化算法,JVM人体工程学将忽略Xms扩展步骤,并更快地保留RAM。 结果,相对于实际使用量的快速增长(蓝色),我们看到了JVM(橙色)的RAM分配要快得多。 因此,即使出现负载峰值,使用G1还是安全的。

中等内存使用量增长

java -XX:+UseG1GC -Xmx2g -Xms32m -jar app.jar 10

在4个周期内,内存在90秒内从32 MiB增长到1 GiB。

有时,要使JVM符合人体工程学,需要几个周期才能找到最佳的RAM分配算法。

G1中型内存使用量增长

如我们所见,JVM在第4 周期中对人体工程学进行了调整,以使垂直扩展在可重复的周期中非常有效

内存使用量增长缓慢

java -XX:+UseG1GC -Xmx2g -Xms32m -jar app.jar 100

内存从32 MiB增长到1 GiB,增量时间增长了大约300秒。 非常灵活和高效的资源扩展符合我们的期望-令人印象深刻。

G1内存使用量增长缓慢

如您所见,橙色区域(保留的RAM)随着蓝色区域(实际使用)的增长而缓慢增加。 因此,没有过量使用或不必要保留的内存。

重要提示:激进堆或垂直缩放

用于提高Java应用程序性能的流行JVM配置通常会阻碍有效地垂直扩展的能力。 因此,您需要在优先级之间进行选择,这些优先级对于您的应用程序最重要。

广泛使用的设置之一是激活积极堆,以最大程度地利用堆的物理内存。 让我们分析一下使用此配置时发生的情况。

java -XX:+UseG1GC -Xmx2g -Xms2g

要么

java -XX:+UseG1GC -Xmx2g -XX:+AggressiveHeap

G1激进堆

如我们所见,保留堆(橙色)是恒定的,并且不会随时间变化,因此容器中没有JVM的垂直缩放。 即使您的应用程序仅使用可用RAM的一小部分(蓝色),其余部分也无法与其他进程或其他容器共享,因为它已完全分配给JVM。

因此,如果要垂直扩展应用程序,请确保未启用主动堆(参数应为-XX:-AggressiveHeap ),也不-XX:-AggressiveHeap -Xms定义为与-Xmx一样高(例如,不要声明-Xmx2g -Xms2g ) 。

并行垃圾收集器

并行是高吞吐量GC,默认情况下在JDK8中使用。 同时,它不适合内存缩减,因此不适合进行灵活的垂直缩放。 为了确认这一点,让我们对示例应用程序进行测试:

java -XX:+UseParallelGC -Xmx2g -Xms32m -jar app.jar 10

平行垃圾收集器

如我们所见,未使用的RAM不会释放回OS。 带有并行GC的JVM可以永久保留它,甚至不考虑显式的Full GC调用。

因此,如果您希望根据应用程序负载从垂直缩放中受益,请将Parallel更改为JDK中可用的收缩GC。 它将所有活动对象打包在一起,删除垃圾对象,并取消提交未使用的内存并将其释放回操作系统。

串行和ConcMarkSweep垃圾收集器

Serial和ConcMarkSweep也在缩小垃圾收集器,并且可以垂直扩展JVM中的内存使用量。 但是与G1相比,它们需要4个完整的GC周期才能释放所有未使用的资源。

让我们看看这两个垃圾收集器的测试结果:

java -XX:+UseSerialGC -Xmx2g -Xms32m -jar app.jar 10

串行垃圾收集器

java -XX:+UseConcMarkSweepGC -Xmx2g -Xms32m -jar app.jar 10

ConcMarkSweep垃圾收集器

从JDK9开始,可以使用新的JVM选项-XX:-ShrinkHeapInSteps加快内存释放速度,该选项在第一个完整GC周期后立即减少已提交的RAM。

雪兰多亚垃圾收集器

Shenandoah是垃圾收集器中的一颗冉冉升起的新星,该垃圾收集器已经被视为即将推出的JVM垂直扩展最佳解决方案。

与其他服务器相比,主要的不同是能够异步收缩(取消提交未使用的RAM并将其释放给OS),而无需调用Full GC。 Shenandoah可以在检测到可用内存后立即压缩活动对象,清理垃圾并将RAM释放回OS。 省略Full GC的可能性可以消除相关的性能下降。

让我们看看它在实践中如何工作:

java -XX:+UseShenandoahGC -Xmx2g -Xms32m -XX:+UnlockExperimentalVMOptions -XX:ShenandoahUncommitDelay=1000 -XX:ShenandoahGuaranteedGCInterval=10000 -jar app.jar 10

在这里,我们添加了雪南多厄可用的一些额外参数:

  • -XX:+UnlockExperimentalVMOptions –启用下面列出的uncommit选项所需
  • -XX:ShenandoahUncommitDelay=1000 –垃圾收集器将开始取消提交超过此时间(以毫秒为单位)的未使用内存。 请注意,当应用程序想要取回内存时,将延迟设置得太低可能会导致分配停顿。 在实际部署中,建议使延迟大于1秒
  • -XX:ShenandoahGuaranteedGCInterval=10000 -这样可以保证在指定的时间间隔(以毫秒为单位)内的GC周期

雪兰多亚垃圾收集器

雪兰多厄非常灵活,只分配必要的资源。 它还压缩了用过的RAM(蓝色),并即时将未消耗的保留RAM(橙色)释放回操作系统,而无需进行昂贵的Full GC调用。 请注意,此GC是实验性的,因此您对稳定性的反馈将对其创建者有所帮助。

结论

Java会不断完善和适应不断变化的需求。 因此,目前,对于微服务和传统应用程序的云托管而言,RAM的需求不再是问题,因为已经有了正确地对其进行扩展,清理垃圾并释放所需过程资源的正确工具和方法。 通过智能配置,Java对于所有项目范围(从云原生启动到传统企业应用程序)都可以具有成本效益。

翻译自: https://www.javacodegeeks.com/2017/11/minimize-java-memory-usage-right-garbage-collector.html

使用正确的垃圾收集器将Java内存使用量降至最低相关推荐

  1. java8默认内存收集器_使用正确的垃圾收集器将Java内存使用量降至最低

    java8默认内存收集器 大小对于软件至关重要. 很明显,与大的整体方法相比,在微服务体系结构中使用小片段具有更多优势. 最新的Java版本的Jigsaw有助于分解旧应用程序或从头开始构建新的云原生应 ...

  2. 搞定常见垃圾收集器【Java】

    (1)JVM的运行模式 Server Client Client的启动比Server模式快,但是长期运行进入稳定期后Server模式的程序运行速度会比Client快,这是因为Server模式启动的是重 ...

  3. 垃圾收集器与Java编程(转载)

    欧阳辰 ( yeekee@sina.com), 周欣 ( zhouxin@sei.pku.edu.cn), 转自:http://www.ibm.com/developerworks/cn/java/l ...

  4. Java内存使用量测试 看看我们天天在用的JVM到底浪费了多少内存资源

    JVM内存使用量测试 测试各种不同的数据结构在JVM中的内存使用量 1 import it.unimi.dsi.fastutil.ints.IntOpenHashSet; 2 3 import jav ...

  5. JVM最佳学习笔记一---Java内存区域与内存溢出异常

    2019独角兽企业重金招聘Python工程师标准>>> 前言 本笔记参照了周志明<深入理解Java虚拟机:JVM高级特性与最佳实践>第三版,读完之后受益匪浅,让我对Jav ...

  6. Java垃圾收集器与内存分配策略详解

    垃圾回收 垃圾Java对象的判断-可达性分析算法 从一系列GCRoots作为起始节点,根据引用关系向下搜索,搜索过程所走过的路径称为"引用链"(Reference Chain),没 ...

  7. 【深入理解Java虚拟机学习笔记】第三章 垃圾收集器与内存分配策略

    最近想好好复习一下java虚拟机,我想通过深读 [理解Java虚拟机 jvm 高级特性与最佳实践] (作者 周志明) 并且通过写一些博客总结来将该书读薄读透,这里文章内容仅仅是个人阅读后简短总结,加强 ...

  8. java中的垃圾收集器_Java中的垃圾收集

    java中的垃圾收集器 Garbage collection in java is one of the advance topic. Java GC knowledge helps us in fi ...

  9. 第3章 垃圾收集器与内存分配策略6

    3.7 选择合适的垃圾收集器 HotSpot虚拟机提供了种类繁多的垃圾收集器,选择太多反而令人踌躇难决,若只挑最先进的显然不可能满足全部应用场景,但只用一句"必须因地制宜,按需选用" ...

最新文章

  1. EasyPusher实现Android手机屏幕桌面直播,实时推送操作画面,用于手游直播等应用
  2. mvp关联activity生命周期_Rxjava+Retrofit统一异常处理与生命周期管理
  3. python程序设计与科学计算pdf_用Python做科学计算 pdf版
  4. java 中调用 Matlab 的函数
  5. PC如何接管手机的双因子身份验证 靠的是英特尔的CPU
  6. Hive 任务卡在 map = 0%, reduce = 0%
  7. css怎样设置li分栏,css怎么对文字分栏
  8. java stream Collectors
  9. 06向量及其坐标表示、向量的方向角与方向余弦、向量组共线与共面的条件、向量的加法与数乘运算、向量组的线性组合、二维向量的基向量分解、三维向量的基向量分解、用坐标做向量的数乘
  10. 梦想成真,喜获微软MVP奖项,微软MVP FAQ?
  11. java学习笔记14-多态
  12. Cydia 不能联网的终极解决方法
  13. 解决在使用rtx2060跑算法时遇到显存不足的问题
  14. (四)HEVC基本理论——变换单元TU
  15. Oracle9查询语句报无法访问oracore9.dll错误的解决方法
  16. PCIE DWC - 3 - PCI-PM Software Compatible Mechanisms
  17. 微软工业计算机主机怎么样,微软Surface Pro 4到底值不值得买?
  18. [Vue warn]: Invalid VNode type: undefined
  19. 动力节点 mysql 郭鑫 34道经典的面试题
  20. matlab e52pt,帮我看看Matlab怎么改这个错误?

热门文章

  1. jsoup怎么获取两个标签之间的text?
  2. JAVA面试常考系列十
  3. Shell入门(四)之数组
  4. java面向对象高级分层实例_数据库操作类
  5. Mysql对字符串去掉前后空格(trim)或者指定字符
  6. 把本地文件上传到gitee
  7. 单例模式——Java
  8. android手机打电话src,【SPILL 百科】SRC:Android 系统的 48kHz 音讯输出限制
  9. mysql切换用户sql语句,MySQL用户管理及SQL语句详解
  10. BigDecimal类的使用