使用英特尔性能计数器调整垃圾收集

介绍

我不得不承认我很震惊。 确实,当我意识到这个出现的日历帖子将涉及垃圾收集时,我感到非常震惊。 GC的主题引起了Java倡导者那些认为内存管理应该是手动的人的热情。 撰写了许多文章,内容涉及看起来奇怪的命令行参数中的细微变化,这些变化对Java应用程序的性能影响很小。 我该如何增加这项庞大的身体工作?

我希望这篇文章不会增加GC的热度,而是让您呼吸新鲜空气。 让我们不要看垃圾回收器消耗的CPU时间或暂停时间; 如何看待内存管理的一个隐藏但潜在的关键方面,尤其是垃圾回收:数据缓存是现代计算机软件设计的主要挑战之一(其他是指令缓存和多核工作分配)。

现代CPU的运行速度如此之快,以至于主内存无法跟上。 可以减轻这种灾难性性能损失中的一部分的方式。 内存被并行拉入高速缓存,然后CPU访问该缓存。 如果我们很幸运,并且代码使CPU几次读取和写入相同的内存(例如在循环内),则CPU可以愉快地访问高速缓存,并且可以免于等待加载和存储到主内存或从主内存中存储。

人们可能会问: “垃圾回收如何影响缓存的性能 ?” 有很多方法,其中有些非常微妙,但是,这里有一些重要的方法:

垃圾收集器遍历内存中的引用。 这导致高速缓存行(高速缓存中的内存块)包含引用周围的内存,因此不再保存程序正在使用的其他数据。

虽然我们将其称为垃圾收集器,但实际上它是分配器,移动器和收集器。 当我们考虑数据缓存时,这确实很重要:

  • 分配:根据硬件规则,内存地址与高速缓存行匹配。 如果内存共享一条高速缓存行,但实际上是从不同的线程访问的,我们会得到一种称为假共享的效果。 但是,如果少量数据散布但从同一线程访问,则缓存利用率很低。
  • 移动:对象在整个生命周期中都不会留在一处。 垃圾收集器通过移动对象来避免内存碎片。 这具有有趣的效果,可以保证与对象关联的高速缓存行在移动后不再与之关联。
  • 收集:有趣的是,收集是一件容易的事。 它可以很简单,只需将内存标记为可重复使用即可。 对象图(多个根)的遍历是为了找出可以收集的内容,这将导致数据高速缓存行负载,从而从用户代码读取或写入的数据中删除高速缓存行。

因此,我们现在可以看到垃圾收集器的设计对于数据缓存的运行至关重要。 交换我们使用的收集器不仅会影响GC暂停和其他明显的问题,而且还会从根本上影响所有用户代码。

一个例子

我不会就此概念发表详尽的科学论文。 这篇文章的目的是展示一种进行JVM调优的替代方法。 因此,我在个人合成器程序Sonic-Field中运行了一个简单,简短,多线程的补丁程序。 该补丁使用反馈,共鸣和其他一些概念来合成弦乐器,然后进行卷积以将声音放置在声学环境中。

选择音场的原因不仅是因为它具有合理的复杂性,高度线程化并使用Spring,还因为我最近发现我可以使用CMS垃圾收集器从中获得更好的性能。 与Sonic-Field的延迟无关紧要,因为它是批处理处理器。 但是,当内存不足时,标准Java 7垃圾收集器与Sonic Field将交换文件写出到磁盘的方式交互不良。 我之所以尝试CMS,是因为它使内存一直处于关闭状态(理论上,不要让我失望),因为它一直在尝试在用户线程旁边进行小的垃圾回收。

如果将所有这些放在一起,我们很可能会提出一个合理的理论
“ CMS垃圾收集器可能会减少暂停时间,也许能够减少内存使用量,但这样做几乎肯定会导致更多数据高速缓存未命中” 。 不断遍历内存中的参考图以尝试收集死对象将导致高速缓存加载,而这些加载将导致从高速缓存中清除其他数据(其大小有限)。 因此,当用户线程再次读取时,它们将导致更多的高速缓存未命中,依此类推。

有关系吗? 答案将完全取决于应用程序,硬件以及应用程序的负载。 我不是,我不再重复,提倡一个垃圾收集器而不是另一个! 尽管如此,这是我想回答的一个问题,所以让我们为我的小测试补丁回答它。

垃圾收集器的这些数据缓存效果在普通的VM分析工具中是不可见的。 这意味着它们在JVM社区中没有得到太多讨论,并且在JVM调优中得到的考虑甚至更少。 但是,有一个工具(实际上是几个,但我将讨论最简单的使用方法)可以使您对该主题有所了解。 我说的是英特尔的PCM(性能计数器监视器)。 它也可以用于代码调整,但我认为今天谈论GC会更有趣。

一个可行的例子

pcm只是命令行工具。 我们通过命令行将引号引起来运行Java并对其进行测量。 通过其他工具,性能计数器可用于获取有关应用程序的各种其他详细信息。 pcm命令行工具的优点在于它的简单性,并且不会干扰整个应用程序的运行。 缺点是它将衡量JVM和应用程序预热阶段。 但是,对于服务器样式的应用程序或批处理处理器(例如Sonic Field),与实际应用程序运行相比,这些开销通常是微不足道的。

我在具有16Gig RAM的个人Macbook Pro Retina(2012)上运行了补丁。 JVM是:

java version "1.8.0-ea"Java(TM) SE Runtime Environment (build 1.8.0-ea-b61)Java HotSpot(TM) 64-Bit Server VM (build 25.0-b05, mixed mode)

当应用程序退出时,从pcm读取的数据将被简单地写入标准输出。 我将运行时没有设置垃圾收集器的设置(因此是默认设置)与当前首选的调整进行了比较。 老实说,我不确定这些调整是否最佳; 我从一系列在线文章中解脱了他们……

这是Java的启动脚本:

/Users/alexanderturner/x/IntelPerformanceCounterMonitorV2.5.1\ 2/pcm.x "java \-Xmx12G -Xms12G  -DsonicFieldTemp=/Users/alexanderturner/temp -DsonicFieldThreads=12 -DsonicFieldSwapLimit=4.0  -XX:+UseConcMarkSweepGC -XX:+UseCompressedOops -XX:ParallelGCThreads=8 -XX:+CMSParallelRemarkEnabled -XX:CMSInitiatingOccupancyFraction=60 -XX:+UseCMSInitiatingOccupancyOnly \-classpath \
bin:\ing-framework-3.1.2.RELEASE/dist/org.springframework.asm-3.1.2.RELEASE.jar:\
spring/sp
spring/sp
rring-framework-3.1.2.RELEASE/dist/org.springframework.beans-3.1.2.RELEASE.jar:\ing-framework-3.1.2.RELEASE/dist/org.springframework.core-3.1.2.RELEASE.jar:\
spring/sprin
spring/spring-framework-3.1.2.RELEASE/dist/org.springframework.context-3.1.2.RELEASE.jar:\
spring/spring-framework-3.1.2.RELEASE/dist/org.springframework.context-support-3.1.2.RELEASE.jar:\
spring/sp
rg-framework-3.1.2.RELEASE/dist/org.springframework.expression-3.1.2.RELEASE.jar:\
spring/spring-framework-3.1.2.RELEASE/dist/org.springframework.test-3.1.2.RELEASE.jar:\
spring/otherJars/commons-logging-1.1.1.jar \com.nerdscentral.sfpl.RenderRunner $1"

希望可以清楚地知道,在IntelPerformanceCounterMonitorV2下运行Java到底有多简单。 因此,这是输出:

标准GC

Core (SKT) | EXEC | IPC  | FREQ  | AFREQ | L3MISS | L2MISS | L3HIT | L2HIT | L3CLK | L2CLK  | READ  | WRITE | TEMP0    0     0.53   0.75   0.70    1.31     422 M    621 M    0.32    0.32    0.14    0.01     N/A     N/A     322    0     0.56   0.77   0.73    1.31     346 M    466 M    0.26    0.31    0.11    0.01     N/A     N/A     281    0     0.22   0.69   0.32    1.31     144 M    192 M    0.25    0.28    0.11    0.01     N/A     N/A     323    0     0.21   0.68   0.31    1.31     135 M    171 M    0.21    0.28    0.10    0.01     N/A     N/A     28
4    0     0.55   0.77   0.71    1.31     332 M    410 M    0.19    0.38    0.11    0.01     N/A     N/A     227    0     0.18   0.68   0.26    1.30     124 M    134 M    0.08    0.30    0.11    0.00     N/A     N/A     275    0     0.19   0.68   0.29    1.31     133 M    155 M    0.14    0.30    0.11    0.00     N/A     N/A     226    0     0.61   0.79   0.78    1.32     343 M    382 M    0.10    0.35    0.10    0.00     N/A     N/A     27-------------------------------------------------------------------------------------------------------------------SKT    0     0.38   0.75   0.51    1.31    1982 M   2533 M    0.22    0.33    0.11    0.01     N/A     N/A     22Instructions retired: 2366 G ; Active cycles: 3166 G ; Time (TSC):  773 Gticks ; C0 (active,non-halted) core resi
-------------------------------------------------------------------------------------------------------------------TOTAL  *     0.38   0.75   0.51    1.31    1982 M   2533 M    0.22    0.33    0.11    0.01     N/A     N/A     N/A
dency: 39.04 %C                 : 1.49 => corresponds to 37.36 % utilization for cores in active stateInstructions per noC1 core residency: 23.92 %; C3 core residency: 0.01 %; C6 core residency: 0.00 %; C7 core residency: 37.02 %C2 package residency: 0.00 %; C3 package residency: 0.00 %; C6 package residency: 0.00 %; C7 package residency: 0.00 %PHYSICAL CORE I
Pminal CPU cycle: 0.76 => corresponds to 19.12 % core utilization over time interval

并发标记扫描

而不是

-XX:+UseConcMarkSweepGC -XX:+UseCompressedOops-XX:+CMSParallelRemark-XX:ParallelGCThreads=8Enabled-XX:CMSInitiatingOccupancyFraction=60-XX:+UseCMSInitiatingOccupancyOnly
Core (SKT) | EXEC | IPC  | FREQ  | AFREQ | L3MISS | L2MISS | L3HIT | L2HIT | L3CLK | L2CLK  | READ  | WRITE | TEMP0    0     0.53   0.69   0.76    1.31     511 M    781 M    0.35    0.35    0.17    0.02     N/A     N/A     262    0     0.54   0.71   0.75    1.31     418 M    586 M    0.29    0.40    0.14    0.01     N/A     N/A     291    0     0.31   0.66   0.47    1.30     207 M    285 M    0.27    0.26    0.11    0.01     N/A     N/A     263    0     0.30   0.66   0.46    1.30     198 M    258 M    0.23    0.27    0.11    0.01     N/A     N/A     29
4    0     0.59   0.73   0.81    1.31     397 M    504 M    0.21    0.46    0.12    0.01     N/A     N/A     297    0     0.30   0.66   0.45    1.30     186 M    204 M    0.09    0.29    0.11    0.00     N/A     N/A     305    0     0.30   0.66   0.45    1.30     188 M    225 M    0.16    0.28    0.11    0.01     N/A     N/A     296    0     0.58   0.73   0.79    1.31     414 M    466 M    0.11    0.49    0.13    0.00     N/A     N/A     30-------------------------------------------------------------------------------------------------------------------SKT    0     0.43   0.70   0.62    1.31    2523 M   3313 M    0.24    0.38    0.13    0.01     N/A     N/A     25Instructions retired: 2438 G ; Active cycles: 3501 G ; Time (TSC):  708 Gticks ; C0 (active,non-halted) core resi
-------------------------------------------------------------------------------------------------------------------TOTAL  *     0.43   0.70   0.62    1.31    2523 M   3313 M    0.24    0.38    0.13    0.01     N/A     N/A     N/A
dency: 47.22 %C                 : 1.39 => corresponds to 34.83 % utilization for cores in active stateInstructions per noC1 core residency: 17.84 %; C3 core residency: 0.01 %; C6 core residency: 0.01 %; C7 core residency: 34.92 %C2 package residency: 0.00 %; C3 package residency: 0.00 %; C6 package residency: 0.00 %; C7 package residency: 0.00 %PHYSICAL CORE I 
Pminal CPU cycle: 0.86 => corresponds to 21.51 % core utilization over time interval

这里提供的所有信息都很有趣,但是我想做的最好的事情就是减少案例并测试我对CMS收集器的主张。 为此,我们只需要看两行即可得出每次运行的输出:

Default:SKT    0     0.38   0.75   0.51    1.31    1982 M   2533 M    0.22    0.33    0.11    0.01     N/A     N/A     22Instructions retired: 2366 G ; Active cycles: 3166 G ; Time (TSC):  773 Gticks ; C0 (active,non-halted) core residency: 39.04 %CMS:0     0.43   0.70   0.62    1.31    2523 M   3313 M    0.24    0.38    0.13    0.01     N/A     N/A     25SKT Instructions retired: 2438 G ; Active cycles: 3501 G ; Time (TSC):  708 Gticks ; C0 (active,non-halted) core residency: 47.22 %

讨论区

我们可以看到,在CMS收集器下,缓存未命中率大大提高。 与默认收集器相比,L2遗漏增加了30%,L2遗漏了27%。 但是,以十亿分s为单位的总时间(708CMS / 773默认)表明,所有这些额外的数据丢失并没有对所有性能产生负面影响。 我想这意味着在就此应用程序的正确方法得出任何结论之前,可以而且应该做更多的研究!

如果您以我未充分讨论该主题为由而离开,则您是正确的。 我的目的是使读者对Java性能的这一方面感兴趣并为新方法打开大门。

参考:在Java Advent Calendar博客上,可以使用JCG合作伙伴 Attila Mihaly Balazs的英特尔性能计数器来调优垃圾回收 。

翻译自: https://www.javacodegeeks.com/2013/12/using-intel-performance-counters-to-tune-garbage-collection.html

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

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

相关文章

matlab2010a连接mysql_MATLAB2010a+OpenCV2.3.1+VS2010运行TLD

出现matlab不显示C编译器的原因主要还是当前Matlab版本相对于VS来说不够新,比如14版的肯定支持10的VS。 本文引用地址: http://blog.csdn.net/shanpohe/article/details/7596401 http://blog.sina.com.cn/s/blog_adfd55190101ejvr.html TLD(Tracking Lea…

理解总结篇—List、Set、Map

List是存储对象的容器&#xff0c;可以存储任意类型的对象且长度可变&#xff0c;List的存储对象是有顺序的&#xff0c;可重复的。 <1> List的接口框架 ArrayList实现类通过数组实现&#xff0c;在向集合中增加或删除时&#xff0c;需要对集合进行增容和拷贝&#xff0c…

SpringBoot+Redis使用jedis实现了对Redis基本类型操作超全工具类

这编文章主要介绍了springboot整合redis&#xff0c;使用jedis实现了对Redis基本类型操作&#xff0c;一些redis的常用命令总结到了一个公共的工具类中,其中使用了fastjson作为了序列化工具。 注&#xff1a;使用了 jdk 1.8 新特性 &#xff0c;jdk版本需要>1.8 一.添加mave…

更改span标签样式_CSS 内嵌样式

前面一节我们讲了行内样式&#xff0c;但是行内样式的缺点就是样式不能重用。例如当有好多个 标签&#xff0c;我们希望所有的 标签的样式都一致&#xff0c;那么需要在每个标签中都写一遍&#xff0c;这么会很麻烦&#xff0c;也会增加很多代码。那么为了解决这个问题&#…

js 函数节流

//es6语法export function debounce(func, delay) {let timer//返回一个函数&#xff0c;并拿到参数return function (...args) {if (timer) {clearTimeout(timer)}timer setTimeout(() > {func.apply(this, args)}, delay)} } //简单实现var debounce function(idle, act…

mysql 6安装当前密码_MySQL8.0 安装踩坑指南

就在昨天上午&#xff0c;刚为云服务器安装好Apache2.4.33和PHP7.2.4环境&#xff0c;准备再来一个最新的MySQL5.7.22。寻找5.7版本的rpm包时下到mysql80xxx.rpm&#xff0c;看人家的教程是mysql57&#xff0c;难道80是MySQL出出…出了8版&#xff0c;一搜新闻2个小时前MySQL发…

如何用Java编写最快的表达式评估器之一

当然&#xff0c;标题有点吸引人&#xff0c;但确实如此&#xff08;您当然不相信自己没有伪造自己的基准&#xff0c;但这是另一回事了&#xff09;。 因此&#xff0c;上周我正在寻找一个小型且可用的库来评估数学表达式。 我几乎直接偶然发现了这个stackoverflow帖子 。 推…

Elasticsearch环境搭建和介绍(Windows)

一、Elasticsearch介绍和安装 1.1 介绍 Elastic Elastic官网&#xff1a;https://www.elastic.co/cn/ Elastic有一条完整的产品线&#xff1a;Elasticsearch、Kibana、Logstash等&#xff0c;前面说的三个就是大家常说的ELK技术栈。 Elasticsearch Elasticsearch官网&#xff1…

python 银行业务系统程序编程写_python多线程实现代码(模拟银行服务操作流程)

1.模拟银行服务完成程序代码目前&#xff0c;在以银行营业大厅为代表的窗口行业中大量使用排队(叫号)系统&#xff0c;该系统完全模拟了人群排队全过程&#xff0c;通过取票进队、排队等待、叫号服务等功能&#xff0c;代替了人们站队的辛苦。排队叫号软件的具体操作流程为&…

vue 新版本 webpack 代理 跨域设置

旧版本中&#xff1a;dev-server.js 这段去掉 var apiRoutes express.Router() //getList apiRoutes.get(/getDiscList, function (req, res) {var url https://c.y.qq.com/splcloud/fcgi-bin/fcg_get_diss_by_tag.fcgaxios.get(url, {headers: {referer: https://c.y.qq.com…

人月神话(2)

我不知道为什么作者要拿外科医生举例子&#xff0c;在我眼里足球队更合适&#xff0c;或者说更贴近生活&#xff0c;让人们更容易理解。人的专业水平&#xff0c;在刚开始其实没什么可比性&#xff0c;试问&#xff1a;一个有小学学历的人和一个有初中学历的人在大公司招聘时有…

mysql查询出过去一个月_Mysql查询今天、昨天、7天、近30天、本月、上一月 数据...

今天select * from 表名 where to_days(时间字段名) to_days(now());昨天SELECT * FROM 表名 WHERE TO_DAYS( NOW( ) ) - TO_DAYS( 时间字段名) < 17天SELECT * FROM 表名 where DATE_SUB(CURDATE(), INTERVAL 7 DAY) < date(时间字段名)近30天SELECT * FROM 表名 where…

Jar Hell变得轻松–用jHades揭秘classpath

Java开发人员将不得不面对的最困难的问题是类路径错误&#xff1a; ClassNotFoundException &#xff0c; NoClassDefFoundError &#xff0c;Jar Hell&#xff0c; Xerces Hell和company。 在本文中&#xff0c;我们将探究这些问题的根本原因&#xff0c;并了解最小的工具&am…

图像处理中常见的时域与频域区别与关系

本文纯为转载只做个人学习记录用&#xff0c;请自动点击链接到作者原文&#xff1a;https://blog.csdn.net/samkieth/article/details/49561539 一、什么是时域 时域是描述数学函数或物理信号对时间的关系。例如一个信号的时域波形可以表达信号随着时间的变化。 二、什么是频域…

程序控制发送文件到邮箱_Kindle电子邮箱推送

Kindle 推送支持的格式目前 Kindle 推送仅支持以下几种格式。需要注意的是&#xff0c;AZW 和 AZW3 是两种不同的格式&#xff0c;虽然这两种格式 Kindle 设备都支持阅读&#xff0c;但是亚马逊的个人文档服务支持推送 AZW 但是不支持 AZW3。Kindle 格式 (.mobi 或 .azw) * 推荐…

[USACO06JAN] 牛的舞会 The Cow Prom

题目描述 The N (2 < N < 10,000) cows are so excited: its prom night! They are dressed in their finest gowns, complete with corsages and new shoes. They know that tonight they will each try to perform the Round Dance. Only cows can perform the Round D…

前端js 实现文件下载

https://www.zhangxinxu.com/wordpress/2017/07/js-text-string-download-as-html-json-file/ 侵删 1.H5 download属性 function downFile(content, filename) {// 创建隐藏的可下载链接var eleLink document.createElement(a);eleLink.download filename;eleLink.style.disp…

mysql的英文字母_MySQL中查询的有关英文字母大小写问题的分析

mysql数据库在做查询时候&#xff0c;有时候是英文字母大小写敏感的&#xff0c;有时候又不是的&#xff0c;主要是由mysql的字符校验规则的设置决定的&#xff0c;通常默认是不支持的大小写字母敏感的。1. 什么是字符集和校验规则&#xff1f;字符集是一套符号和编码。校对规则…

JDK8 lambda的会话指南–术语表

上次出现…我写了一篇与JDK8为我们提供的新方法有关的文章。 最令我兴奋的功能是lambda。 我必须承认&#xff0c;在即将成为浪子的第一年&#xff08;在此期间&#xff0c;我使用C&#xff03;开发了该产品&#xff09;&#xff0c;我喜欢LINQ和它可以做的漂亮&#xff0c;优雅…

写接口给别人调用 推送数据到我们_我们写了一个超好用的抖音矩阵数据管理工具...

我最近跑了十来个抖音号&#xff0c;遇到一些问题&#xff0c;然后通过我们NB的程序员解决了。如果你也在做抖音矩阵&#xff0c;那这些问题你肯定也会遇到&#xff0c;所以我把解决问题的方法工具化了&#xff0c;给大家用。我遇到的最大的问题&#xff0c;就是账号数据的同步…