Java性能调优:充分利用垃圾收集器

JVM背后发生了什么,垃圾回收如何影响Java性能?

性能调优世界是一个危险的地方,一个JVM标志失衡,事情很快就会变得繁琐。 因此 ,我们决定求助于Java性能调优专家, 单调 JVM探查器mjprof的创建者Haim Yadid 。 在这篇文章中,我们将分享他在实践中经受住考验的一些见解,并了解JVM内部在压力下的表现。

新帖:Java性能调优–如何充分利用垃圾收集器http://t.co/NnzQpuWBHz pic.twitter.com/8zqMrUfSHl

— Takipi(@takipid) 2015年4月2日

了解您要面对的问题

JVM受到垃圾收集暂停的影响,该暂停的频率和持续时间各不相同。 在暂停过程中,一切都停止了,各种意外行为开始发挥作用。 当面对一个新的调优项目时,通常会发生以下两种情况之一:公司已经知道它存在垃圾回收问题,或者很快就会发现它有一个问题。 在此阶段,他们很可能会遇到暂停,JVM卡住的不稳定行为以及性能普遍下降。 这些症状通常是通过响应时间慢,CPU和内存利用率高或系统在大多数情况下正常运行而具有不规则行为(例如,极其缓慢的事务和断开连接)而可见的。

主要陷阱:忽略异常值

可以通过一种常见的错误来忽略这种行为,并且不会向任何人发出警报,这是一个常见的错误:测量平均交易时间,并忽略异常值。 这就是GC问题隐藏的地方:尽管大多数情况下系统可能表现正常,但有时系统的响应能力却会下降,并给许多用户带来不良的体验。 例如,一个通常需要100毫秒的事务会受到GC暂停的影响,并突然花费几秒钟甚至一分钟。 在电子商务站点中,如果系统的维护人员仅查看平均交易时间,则除用户以外的任何人都不会注意到。 另一个容易被忽视的问题是,当系统吞吐量受到影响时(例如命中率达到20%),并且它无法充分发挥其潜力。 您可能永远不会知道出了什么问题,因为您没有查看正确的指标。 很多时候,原因是对GC开销的了解不足,并且只关注平均响应时间的一个指标,而忽略了第99个百分位数。

定义性能要求:频率和持续时间

这里的主要问题是:您认为应用程序中GC暂停频率和持续时间的可接受标准是什么? 例如,每天暂停15秒可能是可以接受的,而30分钟一次的频率对产品来说绝对是灾难。 这些要求来自每个系统的领域,在这些领域中,实时和高频交易系统将具有最严格的要求。

总体而言,看到15到17秒的停顿并不罕见。 某些系统甚至可能达到40-50秒的暂停,Haim也有机会在具有大量批处理工作的大堆的系统中看到5分钟的暂停。 因此,暂停持续时间在这里并不重要。

停止世界收集数据:GC日志的重要性

在基于HotSpot JVM的系统中,垃圾收集状态最丰富的数据源是GC日志。 如果您的JVM没有生成带有时间戳的GC日志,那么您就错过了用于分析和解决暂停问题的重要数据源。 这对于开发环境,登台,负载测试以及最重要的是在生产中都是如此。 您可以获取有关系统中所有GC事件的数据,无论这些事件是同时完成的还是引起世界停顿的:这些事件花费了多长时间,消耗了多少CPU以及释放了多少内存。 从这些数据中,您可以了解这些暂停的频率和持续时间,它们的开销,然后继续采取行动以减少它们。

-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:mygclogfilename.gc

GC日志数据收集的最小设置

从指标来看,5%通常是可接受的GC开销的上限,而一个应用程序与另一个应用程序之间可接受的暂停时间却大不相同。

这里值得提及的两个用于GC日志分析的工具是Github上可用的开源GC Viewer和jClarity的Censum 。

解决方案策略

获得所需信息后,就可以检查可能的原因和解决方案了。 您进行的每项更改都要求进行一次新测试,并进行一轮日志收集,以评估其有效性并确定它是否有助于我们前进并达到要求。 优选在生产中和在压力下。 我们可以通过4种主要方法来解决由GC暂停引起的问题:切换垃圾收集器,调整控制Java堆的标志,更改代码以及使用其他JVM /收集器。 以下是对HotSpot领域中考虑的方法及其解决的问题类型的快速概述:

1.错误的垃圾收集器正在运行

粗略地说,JVM有4个垃圾收集器,您可以选择在启动期间使用哪个垃圾收集器。 要了解有关每种类型的更多信息,可以在此处查看比较。 GC问题的一个常见原因是针对您正在开发的应用程序类型使用了错误的收集器。 HotSpot的默认值是并行/吞吐量收集器,通常它不是您的应用程序的最佳选择。 选择正确的收集器的行为(通过JVM标志)是对系统优先级的声明,通常是要考虑的第一个问题。 通常,大多数并发的CMS和G1收集器将导致较少的暂停时间。 尽管出现暂停时,其持续时间可能会比Parallel收集器引起的持续时间长,因为其回退机制是单线程的(Ouch)。 另一方面,对于相同大小的堆,并行收集器将实现更高的吞吐量。 另一个准则与可预测性有关,如果可预测的性能是一个重要因素并且堆大小不大,那么并行收集器可能就是答案。 而且,如果平均响应时间/延迟是您的重中之重,则CMS或G1最有可能是答案。

2.调优Java堆

选择了首选的GC算法之后,该进行一些调整了。 测量(通过GC日志)吞吐量和暂停时间分布,如果您对此感到满意,那就完成了。 如果GC开销很高(并且吞吐量很低),通常增加堆大小将改善这种情况。 当要解决CMS或G1的长时间停顿时,情况就更加棘手。 造成碎片化的另一个原因是,JVM无法跟上对象从新一代迁移到旧一代的速度,然后需要暂停应用程序对其进行修复。 解决方案是更早启动GC或增加堆大小。

从经验来看,堆大小通常在1GB到8GB之间,而更大的堆则更为罕见。 在精简过程中,通常会在调整过程中将堆大小增加到8GB以上。 较大的堆大小的一个可行原因是,当我们想要创建一个大的缓存时,但这也可以在堆外解决。

让我们来看另一个示例,以说明需要调整溢出率的位置。 假设应用程序需要100MB的空间来处理某些请求,而新一代的大小为50MB。 不应该出现在旧一代中的对象将很快到达那里。 调整新世代和幸存者空间将需要解决这个问题,并确保短暂生命的物体将在新世代中终结它们的生命。 影响这里的主要因素是堆大小,新旧发电比,幸存者空间大小以及最大使用期限阈值–一个对象移动到旧发电需要多少GC周期。

我们需要考虑的另一个重要因素是应用程序的“实时设置”。 意味着长时间保留在内存中的对象的大小,例如,活动集的示例将是一个应用缓存,其中包含频繁的数据库查询结果集。 在调整JVM时,需要确保“ liveset”可以方便地容纳在旧版本中,并且除了消耗之外,该区域还具有足够的可用内存。 否则,将严重破坏JVM的行为,从而导致低吞吐量和频繁的暂停。

3.架构和代码更改

一些问题将迫使我们诉诸代码,甚至可能进行体系结构更改。 我们可以在此处解决的麻烦原因之一就是碎片化。 CMS收集器的长时间停顿可能是由旧一代的碎片导致的。 每个GC周期都会释放旧一代的内存块,使其看起来像瑞士奶酪,直到JVM 不能处理的时刻到来。 当JVM将来自新一代的对象移动到比这些“漏洞”更大的对象上,然后必须停止应用程序来解决问题时,就会发生这种情况。 状态随时间变化的应用程序必然会导致碎片化。 随着状态随着时间的推移而变化,“旧状态”对象将从旧版本中释放,而它们的替换状态在新一代中创建。 当它最终晋升为老一代时,它可能会不适用于正确的地方,这将导致碎片化。

对这类问题的体系结构解决方案可能是将对象更新到位,将“状态”移到堆外机制或拆分进程,对延迟敏感的关键路径,其中有许多短期分配的对象到一个进程,将大状态移到另一个进程一。

4.替代的JVM和垃圾收集器

如果暂停时间对您的应用程序至关重要,并且Hotspot JVM无法提供可接受的响应时间,则还有两个可能的选择。 第一个是具有不间断C4垃圾收集器的Azul Zing JVM 。 为了开始使用Zing,您将需要具有相对较大的计算机,并且堆大小必须从32GB开始。 另一个尚不成熟的选择,但如果您想生活在边缘,可能值得一试。这是Shenandoah GC算法。 它使用了一种称为布鲁克转发指针的技术,该技术导致超低的暂停时间和合理的开销。

进一步阅读:领先的GC专家

为了更深入地了解Garbage Collection和JVM的内部,以下是在GC领域中一些最有趣的人:

  • 查理·亨特 ( Charlie Hunt )是Oracle Java平台小组的成员,也是Java Performance一书的主要作者。
  • C4不间断垃圾收集器的创建者Azul Systems的首席技术官兼联合创始人Gil Tene 。
  • 性能调整和jClarity首席技术官兼联合创始人Kirk Pepperdine 。
  • Monica Beckwitt ,Java / JVM性能顾问。
  • Twitter的JVM / GC工程师Tony Printezis ,Oracle的前G1技术负责人。
  • Oracle的JVM开发人员Jon Masamitsu 。
  • Christine H. Flood和Roman Kennke ,Shenandoah GC算法的开发人员。

结论

垃圾回收是JVM中最引人入胜的主题之一,我们希望本文能帮助您更好地了解各个运动部件。 非常感谢Haim Yadid同意与我们分享他的经验! 如果您有任何疑问或想要澄清,请在下面的评论部分中告诉我们。

翻译自: https://www.javacodegeeks.com/2015/04/java-performance-tuning-getting-the-most-out-of-your-garbage-collector.html

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

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

相关文章

[单选]物联网产业链的主要产品不包括下列哪一项 - 关于物联网(主讲:柳毅)笔记...

[单选]物联网产业链的主要产品不包括下列哪一项 转载于:https://www.cnblogs.com/scgw/p/3488452.html

java web读取excel_JavaWeb使用POI操作Excel文件实例

1.为项目添加POI点进去之后下载(上边的是编译好的类,下边的是源代码)解压文件夹,把下面三个文件复制到WebComtent>WEB-INF>lib文件夹下再把这三个文件复制到Tomcat的lib文件夹下,否则Tomcat会因为找不到类而报错(这个地方郁闷了一上午)…

架构大型企业Java项目–我的虚拟JUG会话

昨天我很荣幸被邀请参加虚拟JUG 。 这是一个很大的荣誉,其原因有很多:首先,我是vJUG董事会的一员,其次,因为这是我第二次向这个对Java感兴趣的伟大团队做演讲。 被邀请回来总是很高兴的。 架构大型企业Java项目 过去&…

javascript操作cookie

1. 什么是cookie? Cookie就是浏览器保存在计算机上面的一下信息。一般是保存用户登录状态,就是说Cookie会保存用户登录某个网站的信息在本地,下次这个用户访问网站的时候会自动取出他的Cookie信息,方便定制用户想要的内容。2. 实例…

java 静态方法与实例方法的区别_静态方法与实例方法的区分

Java系列之:看似简单的问题 静态方法和实例化方法的区别Java程序启动class文件被读取时类被加载,如果有static方法,此时会分配内存,非static方法实例化类时才在内存中分配控件存储,引用存储在堆栈中,实体存…

使用wrapper将java程序注册程windows服务后不生效

使用wrapper将java程序注册程windows服务后不生效 使用add.bat或test***.bat测试通过了, 然后使用install***.bat注册后cmd显示注册成功。 但是程序到了运行时间就是不运行!! 解决办法 控制面板 ---> 管理工具 ---> 服务,找…

有简历,为何还要自我介绍?

有简历,为何还要自我介绍? 一个常规的面试,寒暄之后考官提出的第一个面试问题几乎千篇一律:“请你简单地做一下自我介绍”。有些被面试者都会问:简历中情况已经写得很清楚了,这是否多此一举? 要…

java aio聊天_JAVA aio简单使用

使用aio,实现客户端和服务器 对一个数进行轮流累加//服务器端public class Server {private static ExecutorService executorService Executors.newFixedThreadPool(4);public static void main(String[] args) {try {AsynchronousChannelGroup groupAsynchronous…

使用jOOQ的MockDataProvider破解简单的JDBC ResultSet缓存

某些查询不应该一直访问数据库。 例如,当您查询主数据 (例如系统设置,语言,翻译等)时,您可能希望避免一直通过网络发送相同的愚蠢查询(和结果)。 例如: SELECT * FROM l…

ASP.NET内置对象

Request[从浏览器获取信息] QueryString:获取HTTP查询字符串变量集合 Path:获取当前请求的虚拟路径 UserHostAddress:获取远程客户端的IP主机地址 Browser:获取有关正在请求的客户端浏览器功能的信息 Form:获取窗体变量的集合 Url:获取当前请求的URL信息 MapPath():返回与Web服…

java爬虫新闻网站_java爬虫 之 搜狐新闻爬虫(一)

最近开始学习java爬虫,网上很多教程,自己找的时候花了好久的时间去理解别人的思路。打算将自己最近的学习进度稍作整理,理清思路。主要工具使用jsoup:具体用法看http://blog.csdn.net/u012315428/article/details/51135640下面是获…

easyui源码翻译1.32--ValidateBox(验证框)

前言 使用$.fn.validatebox.defaults重写默认值对象。下载该插件翻译源码 validatebox(验证框)的设计目的是为了验证输入的表单字段是否有效。如果用户输入了无效的值,它将会更改输入框的背景颜色,并且显示警告图标和提示信息。该验证框可以结合form(表单…

java静态方法获取对象_JavaPowerMockito模拟单个静态方法和返回对象

小编典典你想要做的是1的一部分和2的全部的组合。你需要使用PowerMockito.mockStatic为类的所有静态方法启用静态模拟。这意味着可以使用when-thenReturn语法对它们进行存根。但是,当你调用尚未在模拟实例上显式存根的方法时,你正在使用的2个参数的mathS…

从战中反弹:将Git提交信息作为JSON返回

在某些情况下,我们必须知道部署到远程服务器的Web应用程序的确切版本。 例如,客户可能想知道我们是否已经在服务器X上部署了错误修复程序。 当然,我们可以尝试使用“传统”方法找到该问题的答案。 问题是: 没有人不记得是谁更新…

在论坛中出现的各种疑难问题:日志收缩问题

最近,在论坛中,遇到了不少疑难的问题,在此特别记录,同时也感谢发帖人的分享、以及其他网友的热心回答。 1、日志暴大,无法收缩,谁来挑战一下! http://bbs.csdn.net/topics/390674731?page1#pos…

学java前要学css_教你一招:学习Java必须学会的CSS用法

一:CSS概述什么是CSSCSS就是层叠样式表(Casading Style Sheets),通常称为CSS样式表,或者是级联样式表。主要用于设置HTML中的文本,内容(字体,大小,对齐),图片外形(宽高,边框样式&…

标准I/O库之缓冲

标准I/O库提供缓冲的目的是尽可能减少使用read和write调用的次数。它也对每个I/O流自动地进行缓冲管理,从而避免了应用程序需要考虑这一点所带来的麻烦。 标准I/O提供了三种类型的缓冲: (1)全缓冲。这种情况下,在填满标…

java如何写安卓接口文档_android、java制作sdk以及自动生成文档

最近一直在做android开发,昨天经理让我写个接口SDK做个接口文档,以便后面的开发。这让我很焦灼,SDK怎么做?要是只有敲代码还好。可是那个接口文档!!!文档这东西最讨厌了,头都大了后来…

[转载]jquery cookie的用法

原文地址:http://www.cnblogs.com/qiantuwuliang/archive/2009/07/19/1526663.html jQuery cookie是个很好的cookie插件,大概的使用方法如下 example $.cookie(’name’, ‘value’); 设置cookie的值,把name变量的值设为value example $.cookie(’name’…

21世纪的设计模式:抽象工厂模式

这是我的演讲的第二部分,“ 21世纪的设计模式” 。 此模式在Java代码中到处都有使用,尤其是在更多“企业”代码库中。 它涉及一个接口和一个实现。 该界面如下所示: public interface Bakery {Pastry bakePastry(Topping topping);Cake bak…