Java VM –提防YoungGen空间

您可能从我们以前的面向性能的文章中看到,健康的JVM是实现最佳应用程序性能和稳定性的最重要目标之一。 这样的健康评估通常仅关注主要收集的频率(避免)或检测内存泄漏的存在。 年轻一代空间或短寿命物体的大小和足迹如何? JVM_beware_YG

本文基于一个真实的故事和我们与一位IT客户的最新故障排除经验。 它将通过一个示例应用程序证明,过多的内存占用空间和次要收集的频率可能会引发性能问题,就像其老兄,旧一代或使用期限的空间一样严重。

JVM健康状况诊断

如果您不熟悉JVM调优领域,那么您很快就会意识到,没有适用于所有应用程序的通用解决方案。 无论您可以从各种来源从Web上找到高质量的材料,您仍需要进行尽职调查并正确了解您正在处理的应用程序类型,包括其对JVM GC暂停的敏感性(某些应用程序需要非常较低的JVM暂停时间<1%)。

Java性能分析(包括内存泄漏检测)以及性能和负载测试是为收集所有正确数据以及有关应用程序内存占用量和JVM运行时运行状况的事实而需要执行的额外工作的良好示例。

话虽这么说,“健康的” JVM是什么意思? 请尽您所能回答以下问题。

**如果回答“否”,请假设置信度为90%+,否则回答“我不知道”。

  • 您的Java堆或OldGen空间是否随着时间的流逝而泄漏(在进行重大收集之后)?
  • 您的应用程序当前受大型和/或频繁的JVM GC暂停影响吗?
  • JVM的总体暂停时间是否高于5%或高于已建立的理想基准?
  • 当前,您的应用程序响应时间是否经常受到JVM GC活动的定期影响,并且超出了应用程序的承受能力?
  • 在最近3个月中,您是否观察到java.lang.OutOfMemoryError错误的发生?
  • 您是否在最近3个月内观察到JVM崩溃的发生(带有核心转储和崩溃报告的JVM突然故障)?
  • 您是否认为您的JVM当前不稳定并且/或者需要过多的人工干预(定期重启等)?

如果您回答“是”或“我不知道”,这意味着您或您的生产性能调整团队可以在这里做一些工作,包括查看当前的JVM GC策略。

如果您对所有具有高置信度级别的用户回答“否”,则意味着您可能已经获得了可靠的应用程序和JVM稳定性,祝贺您。 我仍然建议您重新评估主要版本和增量负载预测之间的情况。

青年一代:真的停止世界吗?

正如我们从快速的JVM健康状况评估练习中看到的那样,要点之一是指JVM的总体暂停时间。 这实际上意味着JVM在“停止世界”事件期间花费了多少时间。 在此期间,应用程序线程将被挂起并且不执行任何工作,从而增加了应用程序的响应时间。 该指标至关重要,因为较大的JVM暂停将触发不稳定且不可预测的响应时间。

HotSpot_Heap_Structure

我在过去几年中看到的一个普遍误解是,YoungGen或次要集合是完全透明的,并且不会影响应用程序的响应时间。 如果您的Java堆大小很小(YG空间<1 GB),并且处理的对象生存期或分配率适中,则此语句几乎是正确的。 在这种情况下,如果次要收集执行得非常快(<20 ms)并且执行得不太频繁(每30秒以上),则YoungGen空间贡献的总体JVM暂停时间将保持很小(<< 1%)。 但是,如果YG内存分配率提高(每个请求的占用空间增加,流量激增等),情况可能会很快改变。

我建议以下文章,以获取有关可用于HotSpot JVM的YoungGen空间和并发收集器的更多详细信息。

#Oracle HotSpot主要是并发收集器:CMS vs. G1

  • http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/G1GettingStarted/index.html

#Oracle HotSpot次要收藏详尽介绍

  • http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html
  • http://blog.griddynamics.com/2011/06/understanding-gc-pauses-in-jvm-hotspots_02.html

无论您使用的HotSpot GC策略如何,包括大多数并发的收集器(例如CMS或G1),YoungGen空间收集仍然是“世界停止”事件。 据我们所知, Azul Zing C4是唯一宣传为真正的连续并发压缩收集器的JVM收集器。 目前,我们还没有机会尝试使用该收集器。 我欢迎任何具有C4调优经验的人分享他们的观察结果,尤其是真实的事实数据,而不是像G1这样的大多数并发收集器。

现在,我们已经涵盖了一些理论,下面让我们深入研究示例应用程序,并针对各种YoungGen占用空间和分配比率来回顾性能测试结果。

样本应用规范

为了比较各种YG分配率之间的响应性和JVM暂停时间%,我们根据以下规范创建了一个示例应用程序:

  • 根据以下属性,已创建JAX-RS(REST)Web服务,并通过jvm URI公开了该服务。
@GET@Path("/jvm")@Produces(MediaType.APPLICATION_JSON)public Integer jvm() {}

每次对jvm的调用都执行以下逻辑:

1.分配短期对象的预定大小(适用于快速YG GC)。

此外,在类加载时会分配1 GB的长寿命对象(不适合GC)的初始内存占用空间,以便为CMS收集器创建一些噪音。

YG短期对象的内存分配和OldGen静态保留仅通过按照下面的代码片段创建原始字节值的静态数组即可实现。 根据使用MAT进行的JVM堆转储分析,可以观察到真正的内存占用量。

private final static int LONG_LIVED_OBJ_FOOTPRINT = (1024 * 1024 * 1024);
private final static int SHORT_LIVED_OBJ_FOOTPRINT = (100 * 1024 * 1024);// 1 GB static memory footprint
private final static byte byteArrayLongLivedObj[] = new byte[LONG_LIVED_OBJ_FOOTPRINT];// 100 MB memory allocation (waste) created per execution
public void generateShortLivedObj(String objId) {          byte byteArrayShortLivedObj[] = new byte[SHORT_LIVED_OBJ_FOOTPRINT];
}

OldGen_1GB_retention

最后,在下面找到环境规格和用于创建,执行和监视此YG比较性能测试的软件。

  • 作业系统:Windows 7 @ 64-bit
  • Java EE容器: WildFly 8 Beta1
  • JVM:Oracle HotSpot 1.7 @ 64位,Java堆大小为5 GB(YG空间:1152 MB XX:NewRatio = 3)。 GC收集器:CMS
  • IDE: JBoss Developer Studio 7.0.0.GA
  • JVM监视: JVisualVM
  • JVM内存泄漏分析器: Plumbr 3.0
  • JVM verbose:gc日志分析器: GCMV
  • 性能和负载测试: Apache JMeter 2.9

性能测试结果和观察

以下性能测试模拟了一个现实生活中的应用程序,该应用程序需要处理大量的JVM暂停时间以及在峰值负载下的严重降级。 在模拟每个请求的应用程序内存占用量的改善(减少)之后,执行了3次运行,其中1次作为基线运行,另外2次运行。

基准线

  • 10个并发线程
  • 每个JVM进程每次执行创建100 MB的短期对象

寿命短的对象的内存占用空间可能看起来很极端,但这确实是我们最初要解决的问题。

结果

  • 平均响应时间:140毫秒
  • 吞吐量:68请求/秒
  • JVM总体暂停时间: 25.8%
  • YG收集频率:每秒7个收集
  • GC速度:每分钟308909 MB

JVM_beware_YG1

根据JVisualVM,JVM看起来很健康(没有内存泄漏,稳定且OldGen低等)。 但是,当您在verbose:gc日志中进一步深入研究时,您会发现JVM的总体暂停时间为25.8%,这都是由于YG收集频率过高所致。 这有力地证明了正确分析verbose:gc日志和仅关注JVM持久空间趋势的意义。

YG_Activity_1

JVM_beware_YG2

测试与调整#1

  • 10个并发线程
  • 每个JVM进程每次执行创建50 MB的短期对象

此运行模拟了应用程序占用空间和内存分配率从每个分配的100 MB到50 MB的初始改善。 通过简单地减少每个请求的应用程序内存占用量,我们可以清楚地看到所有数字的改进,特别是吞吐量。

结果

  • 平均响应时间:119 ms -21
  • 吞吐量:79要求/秒+11
  • JVM整体暂停时间: 15.59%-10.21
  • YG收集频率:每秒3-4次收集-3
  • GC速度:每分钟164950 MB -143959

JVM_beware_YG4

JVM_beware_YG5

测试与调整#2

  • 10个并发线程
  • 每个JVM进程每次执行创建5 MB的短期对象

此运行模拟了将应用程序占用空间和内存分配率从100 MB大大降低到每个分配仅5 MB的情况。

结果

  • 平均响应时间:107毫秒-33
  • 吞吐量:90请求/秒+22
  • JVM总体暂停时间: 1.9%-23.9
  • YG收集频率:每2-3秒收集1次*大幅减少
  • GC速度:每分钟15841 MB -293068

JVM_beware_YG6

JVM_beware_YG7

如您所见,对应用程序占用空间和内存分配的最终改进确实将JVM暂停时间显着减少到了可接受的1.9%。 重要的是要注意,在这3个测试中,OldGen占用空间和CMS活动对JVM暂停时间没有任何实质性影响,性能问题是由于活动过多以及与YG相关的世界停止事件数量过多所致集合。

解决方案和建议

我们的问题案例表明,通过调整和减少每个应用程序请求的内存占用空间,可以减少与过多的YG收集活动相关的JVM暂停时间,从而降低分配率和YG GC频率。

但是,当短期内无法使用这种调整策略时,值得探索其他解决方案。 通过以下能力改进策略可以潜在地获得类似的结果:

  • 水平和垂直扩展:通过增加数量的JVM进程来拆分流量,但以可用硬件为代价,从而降低了YG集合的分配率和频率。 从本质上讲,这意味着将硬件投入该问题。 我的建议始终是先微调您的应用程序内存占用量,然后并行探索其他扩展选项。
  • Java堆大小和YG比率调整:增大YG空间的大小肯定会有助于减少停止世界YG集合的频率。 现在请小心,不要使“旧Gen”空间“饿死”,否则您将直接解决问题,并产生更严重的后果,例如JVM抖动和OOM事件。

最后的话

我希望您喜欢本文,并且现在更好地了解过多的JVM YG集合对性能的潜在影响。

我建议您阅读本文后做以下练习:

  • 选择您最繁忙的应用程序之一。
  • 查看verbose:gc日志,并通过GCMV确定JVM暂停时间。
  • 确定YG收集的频率和影响,并确定调整机会。

期待您的意见,并分享您的JVM调优经验。

参考: Java VM –在Java EE支持模式博客上,请我们的JCG合作伙伴 Pierre Hugues Charbonneau 注意YoungGen领域 。

翻译自: https://www.javacodegeeks.com/2013/11/java-vm-beware-of-the-younggen-space.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/366855.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

小程序绘图工具painter-json文件绘制保存分享图-可点击任意元素触发函数

Painter是由酷家乐移动前端团队打造的一款小程序绘图组件。 原项目地址&#xff1a;https://github.com/Kujiale-Mobile/Painter 新版地址&#xff1a;https://github.com/shesw/Painter 这款交互版原来是为了针对业务中的新需求而由我自己开发的&#xff0c;后来需求改动&a…

sweetalert php,SweetAlert插件

用户#姓名操作{% for user in all_user %}{{ forloop.counter }}{{ user.username }}编辑删除{% endfor %}var _thisthis;swal({title:"你确定要删除吗&#xff1f;",text:"删除可就找不回来了哦&#xff01;",type:"warning",showCancelButton:…

python集合以及编码初识

一.集合 set 集合是无序的,天然能去重,是可变的.例:s {1,2,3,4,5}   1 s {} 2 s1 {1} 3 print(type(s)) # 空{}就是字典 4 print(type(s1)) #集合 集合的基本操作: 1.增 s {1,2,3,22,,ss,(3,4)} s.add(元素) s.update(alex) #迭代添加 alex会被分割添加 2.删 s…

JS 字符串操作总结

【MDN】https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String 【参考】https://www.cnblogs.com/guoyeqiang/p/8178336.html 字符串转换 1、toString() var age 11; var ageAsString age.toString(); //字符串“11” var found true;…

4 张动图解释为什么(什么时候)使用 Redux

dev-reading/fe 是一个阅读、导读、速读的 repo&#xff0c;不要依赖于 dev-reading/fe 学习知识。本 repo 只是一个快速了解文章内容的工具&#xff0c;并不提供全文解读和翻译。你可以通过本平台快速了解文章里面的内容&#xff0c;找到感兴趣的文章&#xff0c;然后去阅读全…

您正在使用什么垃圾收集器?

我们的研究实验室正全速前进。 随着最近的资金注入 &#xff0c;我们只能保证我们不断创新的步伐只会加快。 我们进行的部分研究与GC优化有关。 在处理这个有趣领域中的问题时&#xff0c;我们认为可以分享一些有关GC算法使用的见解。 为此&#xff0c;我们对使用特定GC算法的…

基于混沌的图像置乱加密算法及matlab的实现,基于混沌的图像置乱加密算法及MATLAB的实现...

基于混沌的图像置乱加密算法及MATLAB的实现提出了一种基于混沌映射的图像置乱加密算法。借助MATLAB6.5软(本文共3页)阅读全文>>数字水印(Digital Watermark)技术属于国际上新兴的研究领域,其主要目的是为了实现数字作品的版权保护,将与作品内容相关或不相关的一些标示信息…

poj1857 To Europe! To Europe!

思路&#xff1a; 一维dp。 实现&#xff1a; 1 #include <cstdio>2 #include <iostream>3 using namespace std;4 const int INF 0x3f3f3f3f;5 int w[1005], v[1005], sum[1005];6 double dp[1005];7 int main()8 {9 int b, l, n; 10 while (cin >>…

前端布局推进剂 - 间距规范化

我是一个爱折腾设计的前端&#xff0c;一直都在标榜自己的页面还原是多么的牛 X 。怎么做到页面还原&#xff1f;我有一个最笨但是有效的方法&#xff0c;就是把设计稿直接存成图片&#xff0c;作为背景图然后临摹着设计稿进行开发。我觉得自己太有才了。像素级还原有没有&…

战略模式并不意味着春天!

是的&#xff0c;所以可以说您正在编写一个Spring MVC应用程序&#xff0c;然后您决定&#xff1a;“我想做一些单独的封装算法&#xff0c;这些算法可以互换来执行特定的行为”。 对此的经典回应是“您需要一个战略模式男孩&#xff01;”。 所以&#xff0c;这就是我所做的&…

echarts折线图相关

optionJKDLine {  title: {text: 告警数量趋势图,textStyle:{  //标题样式fontStyle:normal,fontFamily:sans-serif,fontSize:12    }},tooltip: {trigger: axis},legend: {  //图例,默认显示},grid: {  //图表距离left: -3%,right: 5%,bottom: 3%,top:20%,contai…

南邮java实验报告,南邮微机原理实验报告精选.doc

南邮微机原理实验报告精选《微型计算机原理与接口技术》上机实验学 院&#xff1a; 电子科学与工程专 业&#xff1a; 电磁场与无线技术姓 名&#xff1a; 陈秀慧课 程 号&#xff1a; B0300062S学 号&#xff1a;任课老师&#xff1a; 欧晓鸥2016年 3 月 21日实验目的熟悉第四…

Mybatis动态SQL语句使用

在实际开发中&#xff0c;有时候查询条件可能是不确定的&#xff0c;查询条件可能有多条也可能没有&#xff0c;这时候就需要用到动态的sql语句拼接功能。 一、if、where、sql标签的使用 需求&#xff1a;在一些高级查询中&#xff0c;查询条件存在的个数不确定。如&#xff0c…

为什么Vue不能观察到数组length的变化?

官网解释如下 由于 JavaScript 的限制&#xff0c;Vue 不能检测以下变动的数组&#xff1a; 当你利用索引直接设置一个项时&#xff0c;例如&#xff1a;vm.items[indexOfItem] newValue 当你修改数组的长度时&#xff0c;例如&#xff1a;vm.items.length newLength 因为vue…

规则引擎drools的简单使用

规则引擎适用于有复杂多变的规则&#xff0c;如商品满减、积分赠送、考勤规则等 一、引入maven依赖 <dependency><groupId>org.drools</groupId><artifactId>drools-core</artifactId><version>7.13.0.Final</version> </depende…

使用MongoDB进行乐观锁定重试

在我以前的文章中&#xff0c;我谈到了对MongoDB批处理程序采用乐观锁定的好处。 如我之前所写&#xff0c;乐观锁异常是可恢复的异常&#xff0c;只要我们获取最新的Entity&#xff0c;我们就会对其进行更新并保存。 因为我们使用的是MongoDB&#xff0c;所以我们不必担心本地…

cx oracle 配置,cx_Oracle的配置啊。。终于搞出来了

参考。。http://www.blogjava.net/jelver/articles/294583.htmlhttp://shanchao7932297.blog.163.com/blog/static/1363624200710911543428/http://aofengblog.blog.163.com/blog/static/6317021201157111336764/http://www.cnblogs.com/ysisl/archive/2010/12/20/1911870.html…

JavaScript中发布/订阅模式的理解

订阅发布模式的介绍 发布订阅模式&#xff0c;它定义了一种一对多的关系&#xff0c;可以使多个观察者对象对一个主题对象进行监听&#xff0c;当这个主题对象发生改变时&#xff0c;依赖的所有对象都会被通知到。 在生活中我们常常遇到这样一种情况&#xff0c;我们在使用新…

java的list遍历

for(String str : list) {//增强for循环&#xff0c;其内部实质上还是调用了迭代器遍历方式&#xff0c;这种循环方式还有其他限制&#xff0c;不建议使用。System.out.println(str); } for( int i 0 ; i < list.size() ; i) {//普通for循环&#xff0c;内部不锁定&#xf…

Spring Data Solr入门

Spring Data Solr是Spring Data项目的扩展&#xff0c;该项目旨在简化Apache Solr在Spring应用程序中的使用。 请注意&#xff0c;这不是Spring&#xff08;数据&#xff09;或Solr的简介。 我认为您至少对这两种技术都有一些基本的了解。 在下面的文章中&#xff0c;我将展示如…