垃圾收集:提高吞吐量

全蛇 这篇文章的灵感来自于在内存管理术语中的“ Pig in the Python ”定义。 显然,该术语用于解释GC反复促进大对象世代相传的情况。 据推测,这样做的效果类似于Python吞下整个猎物,只是在消化过程中被固定住了。

在接下来的24小时里,我简直无法理解令人窒息的python的图片。 就像精神科医生所说的那样,消除恐惧的最好方法就是谈论它们。 所以我们开始。 但是,除了Python,其余的故事都是关于垃圾收集优化的。 我承诺。

垃圾收集暂停是众所周知的性能瓶颈。 现代JVM确实带有高级垃圾收集器,但是据我所知,为特定应用程序找到最佳配置仍然很困难。 为了有机会手动解决该问题,需要了解垃圾收集算法的确切机制。 这篇文章可能会在这方面为您提供帮助,因为我将使用一个示例来演示JVM配置中的微小更改如何影响应用程序的吞吐量。

我们用来演示GC对吞吐量影响的应用程序很简单。 它仅包含两个线程:

  • PigEater –模拟一种情况,Python不断吃掉另一头猪。 该代码通过在java.util.List中添加32MB字节并在每次尝试后休眠100ms来实现此目的。
  • PigDigester –模拟异步摘要过程。 该代码仅通过使该猪列表无效来实现消化。 由于这是一个相当累的过程,因此在每次参考清洁后,该线程将休眠2000ms。

两个线程都会在while循环中运行,继续吃和消化,直到蛇吃饱为止。 大约有5,000头猪被吃掉。

package eu.plumbr.demo;public class PigInThePython {static volatile List pigs = new ArrayList();static volatile int pigsEaten = 0;static final int ENOUGH_PIGS = 5000;public static void main(String[] args) throws InterruptedException {new PigEater().start();new PigDigester().start();}static class PigEater extends Thread {@Overridepublic void run() {while (true) {pigs.add(new byte[32 * 1024 * 1024]); //32MB per pigif (pigsEaten > ENOUGH_PIGS) return;takeANap(100);}}}static class PigDigester extends Thread {@Overridepublic void run() {long start = System.currentTimeMillis();while (true) {takeANap(2000);pigsEaten+=pigs.size();pigs = new ArrayList();if (pigsEaten > ENOUGH_PIGS)  {System.out.format("Digested %d pigs in %d ms.%n",pigsEaten, System.currentTimeMillis()-start);return;}}}}static void takeANap(int ms) {try {Thread.sleep(ms);} catch (Exception e) {e.printStackTrace();}}
}

现在让我们将该系统的吞吐量定义为“每秒消化的猪的数量”。 考虑到每100毫秒后将猪塞入python,我们看到该系统的理论最大吞吐量因此可以达到10头/秒。

配置GC示例

让我们来看一下使用两种不同配置的系统行为。 在所有情况下,该应用程序都是使用具有8G物理内存的双核Mac(OS X 10.9.3)运行的。

第一种配置:

  • 4G堆( -Xms4g –Xmx4g
  • 使用CMS清理旧的(-XX:+ UseConcMarkSweepGC ),并并行清理年轻的-XX:+ UseParNewGC
  • 已将堆的12,5%(- Xmn512m )分配给年轻一代,从而进一步将Eden和Survivor空间的大小限制为相同大小。

第二种配置有些不同:

  • 2G堆( -Xms2g –Xmx2g
  • 使用并行GC在年轻一代和终身一代中进行垃圾收集( -XX:+ UseParallelGC
  • 已将堆的75%分配给年轻一代( -Xmn1536m

现在该下赌注了,哪种配置在吞吐量方面表现更好(每秒吃掉的猪,还记得吗?)。 你们那些花钱买第一种配置的人,我一定会让您失望的。 结果完全相反:

  • 第一种配置(大堆,较大的旧空间,CMS GC)每秒可以吃掉8.2头猪
  • 第二种配置(较小的堆2倍,较大的幼小空间,并行GC)每秒可吞噬9.2头猪

现在,让我对结果进行透视。 分配的资源减少了2倍(在内存方面),我们的吞吐量提高了12% 。 这与常识相反,可能需要进一步澄清实际发生的情况。

解释GC结果

您所面对的原因并不是太复杂,而当您更仔细地观察测试运行期间GC的操作时,答案就直盯着您。 为此,您可以使用自己选择的工具,我在jstat的帮助下进行了深入研究,类似于以下内容

jstat -gc -t -h20 PID 1秒

查看数据,我注意到第一个配置经历了1,129个垃圾回收周期(YGCT + FGCT),总共花费了63.723秒:

Timestamp        S0C    S1C    S0U    S1U      EC       EU        OC         OU       PC     PU    YGC     YGCT    FGC    FGCT     GCT   
594.0 174720.0 174720.0 163844.1  0.0   174848.0 131074.1 3670016.0  2621693.5  21248.0 2580.9   1006   63.182  116 	0.236   63.419
595.0 174720.0 174720.0 163842.1  0.0   174848.0 65538.0  3670016.0  3047677.9  21248.0 2580.9   1008   63.310  117 	0.236   63.546
596.1 174720.0 174720.0 98308.0 163842.1 174848.0 163844.2 3670016.0   491772.9  21248.0 2580.9   1010   63.354  118 	0.240   63.595
597.0 174720.0 174720.0  0.0   163840.1 174848.0 131074.1 3670016.0   688380.1  21248.0 2580.9   1011   63.482  118 	0.240   63.723

第二种配置总共暂停了168次(YGCT + FGCT),仅11.409秒。

Timestamp        S0C    S1C    S0U    S1U      EC       EU        OC         OU       PC     PU    YGC     YGCT    FGC    FGCT     GCT   
539.3 164352.0 164352.0  0.0    0.0   1211904.0 98306.0   524288.0   164352.2  21504.0 2579.2 	27    2.969  141 	8.441   11.409
540.3 164352.0 164352.0  0.0    0.0   1211904.0 425986.2  524288.0   164352.2  21504.0 2579.2 	27    2.969  141 	8.441   11.409
541.4 164352.0 164352.0  0.0    0.0   1211904.0 720900.4  524288.0   164352.2  21504.0 2579.2 	27    2.969  141 	8.441   11.409
542.3 164352.0 164352.0  0.0	0.0   1211904.0 1015812.6  524288.0   164352.2  21504.0 2579.2 	27	2.969  141 	8.441   11.409

考虑到在这两种情况下需要进行的工作在以下方面是等效的:–在看不到长寿的物体的情况下,GC在此吃猪活动中的职责只是尽可能快地摆脱一切。 使用第一种配置时,GC仅被迫运行约6.7倍,导致总暂停时间延长约5.6倍。

因此,这个故事实现了两个目的。 首先,最重要的是,我希望我能从头上看到一条令人窒息的Python的照片。 另一个更重要的收获是–调整GC充其量是一项棘手的工作,需要深刻理解几个基本概念。 即使使用本博客文章中使用的真正琐碎的应用程序,您将要面对的结果也会对吞吐量和容量规划产生重大影响。 在实际应用中,差异甚至更加惊人。 因此,选择就是您的选择,您既可以掌握概念,也可以专注于日常工作,并让Plumbr根据您的需求找到合适的GC配置 。

翻译自: https://www.javacodegeeks.com/2014/09/garbage-collection-increasing-the-throughput.html

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

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

相关文章

大叔手记(12):我的一次面试经历(谈大叔如何应对面试官)

本文目的 写本文的目的,大叔不是为了装逼(虽然说话的口气有时候也确实有点装逼,性格导致的,咳。。。我得改),其实大叔在公司也只是小罗罗,本文的目的主要是为了向大家展示如何通过各种软技能应对…

认识Mahout下的云计算机器学习

认识Mahout下的云计算机器学习 Apache Mahout 是 ApacheSoftware Foundation (ASF) 旗下的一个开源项目,提供一些可扩展的机器学习领域经典算法的实现,旨在帮助开发人员更加方便快捷地创建智能应用程序,并且,在 Mahout 的最近版本…

NetBeans 8.0的五个新性能提示

NetBeans 8.0引入了几个新的Java提示 。 尽管有许多与Java Persistence API相关的新提示,但我还是关注Performance类别中的五个新提示。 NetBeans 8.0引入的五个新的“性能提示”是: 已装箱价值的装箱 冗余String.toString() …

机智云小程序启蒙:WebSocket网页控制

机智云小程序启蒙:WebSocket网页控制 机智云Web版的JS远程控制设备,是调用了机智云开放的Open API和WebSocket API来实现的。这个是设计小程序最好的基础,也可以使无安卓设备的用户用网页远程控制设备。 其中,Open API用到的接口…

Web service 超过了最大请求长度错误解决

Web service 超过了最大请求长度错误解决 System.Web.Services.Protocols.SoapException: 运行配置文件中指定的扩展时出现异常。 ---> System.Web.HttpException: 超过了最大请求长度。 在 System.Web.HttpRequest.GetEntireRawContent() 在 System.Web.HttpRequest.ge…

动态规划--图像压缩

<算法设计与分析> --王晓东 题目描述和解析参照&#xff1a;http://blog.csdn.net/liufeng_king/article/details/8648195 他在那里分析得非常的详细。我也是按照这种思路来解的&#xff0c;而且算法设计与实现的课件上也是这么个解法。 主要是理解这个公式&#xff0c;…

oracle 存储过程的基本语法 及注意事项

oracle 存储过程的基本语法 1.基本结构 CREATE OR REPLACE PROCEDURE 存储过程名字( 参数1 IN NUMBER, 参数2 IN NUMBER) IS变量1 INTEGER :0;变量2 DATE;BEGIN END 存储过程名字2.SELECT INTO STATEMENT 将select查询的结果存入到变量中&#xff0c;可以同时将多个列存…

function——函数声明头的提升和预解析

函数&#xff1a; 即function语句的集合&#xff0c;就是将多个语句封装到一起&#xff1b; 函数的执行要会自己遍历&#xff0c;遇见函数 a&#xff08;&#xff09;&#xff1b;执行语句&#xff0c;就要移交控制权&#xff0c;函数执行完毕之后&#xff0c;控制权又移交回…

在JDeveloper 12.1.3中将Java API用于WebSockets

介绍 最新版本的JDeveloper 12c&#xff08;12.1.3.0&#xff09;和WebLogic Server 12.1.3一起提供了一些新的Java EE 7功能。 其中之一是对用于WebSocket的JSR 356 Java API的支持。 实际上&#xff0c;从12.1.2.0版本开始就支持WebSocket协议&#xff08;RFC 6455&#xff0…

【HBuilder】手机App推送至Apple App Store过程

一、前言 最近由于公司同事离职&#xff0c;顶替这位同事从事手机App的研发工作&#xff0c;BIM数据平台部门采用的是HBuilder作为手机App的制作环境。本篇介绍我是如何将HBuilder的Release包发布至App Store的。 二、内容 1. 首先登录Apple Developer网站 2. 点击iTunes Conn…

Java性能调优调查结果(第四部分)

这是系列文章中的最后一篇&#xff0c;我们将分析我们在2014年10月进行的Java Performance Tuning Survey的结果。如果您还没有阅读第一篇文章&#xff0c;我建议您首先阅读以下内容&#xff1a; 性能问题的频率和严重性 最受欢迎的监控解决方案 查找根本原因的工具和技术 …

android eclipse 配置 在项目右击选择properties

转载于:https://www.cnblogs.com/guoxiaoyue/p/3485243.html

减少主要GC暂停的频率

这篇文章将讨论一种技术&#xff0c;以减少应用程序等待时间造成的垃圾收集暂停的负担。 正如我几年前所写&#xff0c; 在JVM中无法禁用垃圾收集 。 但是&#xff0c;有一个巧妙的技巧可以用来大大减少长时间停顿的时间和频率。 如您所知&#xff0c;JVM中发生了两个不同的GC…

WAI-ARIA对自动完成小部件的支持

在本文中&#xff0c;我想讨论AutoComplete小部件的可访问性。 在您键入该字段时&#xff0c;通常会使用“自动完成”窗口小部件提供建议。 在当前的工作中&#xff0c;我基于Twitter的Typeahead &#xff08;一个灵活JavaScript库&#xff09;实现了JSF组件&#xff0c;该库为…

eclipse中java.lang.OutOfMemoryError: Java heap space错误

Myeclipse中报java.lang.OutOfMemoryError: Java heap space错误 解决办法: 选中被运行的类&#xff0c;点击菜单‘run->run Configuration’&#xff0c;选择(x)Argument标签页下的vm arguments框里 输入 -Xmx800m, 保存运行。问题解决 转载于:https://www.cnblogs.com/vig…

[Vue warn]: Invalid prop: custom validator check failed for prop xxx.问题

在用vue ui框架&#xff08;iview、elementui等&#xff09;做项目&#xff0c;会遇到这种问题 这样的&#xff0c;点那都报错&#xff0c;千辛万苦的付出&#xff0c;却找不到问题在哪 其实很简单&#xff0c;报错都显示出那个组件的问题了 ‘<Form>’这个组件&#xf…

CheckList 如何梳理可减少上线的验证时间(总结篇)

对CheckList的执行发起的思考&#xff1f; &#xff08;1&#xff09;功能越来越多&#xff0c;CheckList越补充越多&#xff0c;执行CheckList时间越来越长&#xff0c;如何减少上线的验证时间&#xff1f;&#xff08;2&#xff09;减少上线验证的时间外&#xff0c;如何保证…

PrimeFaces 5.0 DataTable列切换器

我有机会与PrimeFaces 5.0 DataTable一起工作&#xff0c;并且增强功能很棒。 今天&#xff0c;我只想展示其中的一项新功能……DataTable列切换器。 此功能使您可以通过复选框列表选择显示哪些列。 要使用列切换器&#xff0c;只需添加一个commandButton即可将列选择的选择列…

使用JGit API探索Git内部

您是否想过提交及​​其内容如何存储在Git中&#xff1f; 好吧&#xff0c;我有&#xff0c;在上一个下雨的周末&#xff0c;我有一些空闲时间&#xff0c;所以我做了一些研究。 因为我对Java的感觉比对Bash的感觉要多&#xff0c;所以我使用了JGit和一些学习测试来探索提交的…

Html5 布局方式

在Html5之前&#xff0c;统一采用的是Div css的方式进行布局&#xff0c;但是却和开发人员的命名方式&#xff0c;喜好有关。在新的Html5中&#xff0c;布局却显得更加人性化&#xff0c;更易理解了。如增加了Header&#xff0c;Footer&#xff0c;Section&#xff0c;Aside标签…