如今,JVM被认为是智能的。 预期不会进行太多配置–只需设置要在启动脚本中使用的最大堆,您就可以进行了。 所有其他默认设置都很好。 大概我们当中有些人误以为。 实际上,在运行时期间发生了很多事情,无法自动调整性能,因此,在我最近面对的一个案例研究中,我将带您逐步了解要调整的内容和时间。

但是在讨论案例本身之前,先介绍了有关JVM内部的一些背景知识。 以下所有内容均与Oracle Hotspot 7有关。 其他供应商或更早版本的Hotspot JVM很有可能带有不同的默认值。

JVM默认选项

第一站 :JVM尝试确定是否 它正在客户端环境的服务器上运行。 它通过查看体系结构和OS组合来做到这一点。 简单总结:

建筑 CPU /内存 操作系统 默认
i586 任何 微软视窗 客户
AMD64 任何 任何 服务器
64位SPARC 任何 的Solaris 服务器
32位SPARC 2个以上内核和> 2GB RAM 的Solaris 服务器
32位SPARC 1核或<2GB RAM 的Solaris 客户
i568 2个以上内核和> 2GB RAM Linux或Solaris 服务器
i568 1核或<2GB RAM Linux或Solaris 客户

例如,如果您在32位Linux上的Amazone EC2 m1.medium实例上运行,则默认情况下,您将被视为在客户端计算机上运行。

这很重要,因为JVM在客户端和服务器上的优化方式完全不同-在客户端计算机上,它尝试减少启动时间,并在启动过程中跳过一些优化。 在服务器环境上,会牺牲一些启动时间来稍后实现更高的吞吐量。

第二组默认值 :堆大小。 如果您的环境被认为是根据先前准则确定的服务器,则分配的初始堆将是计算机上可用内存的1/64。 在4G机器上,这意味着您的初始堆大小将为64MB。 如果在极低的内存条件下(<1GB)运行,它可能会更小,但是在这种情况下,我将严重怀疑您在做任何合理的事情。 在这个千年中,还没有看到内存少于千兆字节的服务器。 如果有的话,我会提醒您,如今1 GB的DDR成本不到20美元……

但这将是初始堆大小。 最大堆大小将是可用总内存的¼或1GB中的最小值。 因此,在我们的1.7GB Amazon EC2 m1.small实例中,可用于JVM的最大堆大小约为435MB。

下一步 :使用默认垃圾收集器。 如果认为您正在客户端JVM上运行,则JVM所应用的默认值为串行GC( -XX:+ UseSerialGC )。 在服务器级计算机上(同样,请参见第一部分),默认值为并行GC( -XX:+ UseParallelGC )。

默认值还有很多其他事情,例如PermGen的大小,不同的世代调整,GC暂停限制等。但是为了使帖子的大小受到控制,请坚持使用上述配置。 对于好奇的用户-您可以从以下材料中进一步了解默认值:

  • http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html
  • http://docs.oracle.com/javase/7/docs/technotes/guides/vm/gc-ergonomics.html
  • http://docs.oracle.com/javase/7/docs/technotes/guides/vm/server-class.html

案例分析

现在让我们看一下案例研究的行为。 以及我们是否应该凭借决策信任JVM还是跳入我们自己。

我们手头的应用程序是一个问题跟踪器。 即JIRA 。 这是一个在后端具有关系数据库的Web应用程序。 部署在Tomcat上。 在我们的一种客户端环境中表现不佳。 并不是由于任何泄漏,而是由于部署中的不同配置问题。 由于GC暂停时间特别长,这种行为不当的配置导致吞吐量和延迟方面的重大损失。 我们设法帮助了客户,但是出于隐私考虑,我们将不在此处介绍确切的详细信息。 但是案例很好,因此我们继续下载了JIRA ,以演示我们从此实际案例研究中发现的一些概念。

Atlassian的特别之处在于,这些家伙已经附带了一些打包好的负载测试 。 因此,我们有一个基准可用于我们的配置。

我们仔细拆箱了我们新收购的JIRA的包装,并将其安装在64位Linux Amazon EC2 m1.medium实例上。 并进行捆绑测试 。 无需更改默认值。 Atlassian小组将其设置为-Xms256m -Xmx768m -XX:MaxPermSize = 256m

在每次运行期间,我们使用-XX:+ PrintGCTimeStamps -Xloggc:/tmp/gc.log -XX:+ PrintGCDetails收集了GC日志,并在GCViewer的帮助下分析了此统计信息。

结果实际上还不错。 我们将测试运行了一个小时,然后由于垃圾收集暂停而损失了仅151秒 。 占总运行时间的4.2%。 在最坏的情况下,gc的暂停时间为2秒 。 因此,GC暂停会影响此特定应用程序的吞吐量和延迟。 但不要太多。 但是足以作为本案例研究的基准–在我们的实际客户中,GC暂停时间长达25秒。

挖掘GC日志浮出了水面。 Full GC的大多数运行都是由PermGen大小随时间扩展而引起的。 日志显示,测试期间总共使用了大约155MB的PermGen。 因此,通过在启动脚本中添加-XX:PermSize = 170m ,我们将PermGen的初始大小增加到比实际使用的大小更多。 这使总的暂停时间从151秒减少到134秒 。 并将最大等待时间从2,000ms减少到1300ms

然后我们发现了完全出乎意料的事情。 我们的JVM使用的GC实际上是串行GC。 如果您认真地遵循了我们的文章,则情况并非如此-64位Linux机器应始终被视为服务器级机器,并且所使用的GC应该是并行GC。 但显然并非如此。 到目前为止,我们最好的猜测是–即使JVM以服务器模式启动,它仍然会根据可用的内存和内核来选择所使用的GC。 由于此m1.medium实例具有3.75GB内存,但只有一个虚拟内核,因此所选的GC仍是串行的。 但是,如果你们对这个话题有更多的见解,我们渴望找到更多。

尽管如此,我们将算法更改为-XX:+ UseParallelGC并重新运行测试。 结果–累积的停顿进一步减少到92秒最坏情况的延迟也减少到了1200ms

对于最终测试,我们尝试尝试并发标记和扫描模式。 但是该算法对我们完全失败了–暂停时间增加到300秒,延迟增加到5,000毫秒以上。 在这里,我们放弃了,决定叫它一个晚上。

因此,仅使用两个JVM启动参数并花费几个小时来配置和解释结果,我们就有效地提高了应用程序的吞吐量和延迟。 绝对数字听起来并不令人印象深刻– GC暂停从151秒减少到92秒,最坏情况下的延迟从2,000ms减少到1200ms ,但是请记住,这只是一个只有两个配置设置的小型测试。 从%的角度来看–嘿,我们都提高了与GC暂停相关的吞吐量,并将延迟减少了40%

无论如何,我们现在再有一个案例向您展示,性能调整就是关于设定目标,进行测量,调整和重新测量。 也许您和我们一样幸运,只需更改两个配置选项就可以使您的用户更快乐40%……

参考: 您是否应该信任JVM中的默认设置? 由我们的JCG合作伙伴 Nikita Salnikov Tarnovski在Plumbr Blog博客上获得。

翻译自: https://www.javacodegeeks.com/2012/12/should-you-trust-the-default-settings-in-jvm.html

您是否应该信任JVM中的默认设置?相关推荐

  1. jvm默认的初始化参数_您是否应该信任JVM中的默认设置?

    jvm默认的初始化参数 如今,JVM被认为是智能的. 预期配置不多-只需设置要在启动脚本中使用的最大堆,您就可以进行了. 所有其他默认设置都很好. 大概我们当中有些人误以为. 实际上,在运行时期间发生 ...

  2. linux恢复设置文件夹,将.bashrc文件恢复到Ubuntu中的默认设置

    以下介绍在Ubuntu系统中将.bashrc文件恢复默认设置的方法,如果你在Ubuntu系统中把.bashrc文件搞坏了就按下面的方法恢复bashrc文件. 背景 我有一个Ubuntu VM,我经常用 ...

  3. Idea21.1.3版本中Scala默认设置带类型

    1.第一步打开idea[File]->[Setting] 2.搜索栏搜索scala 3.设置 4.(这一步最关键,必须设置)(如果写scala还是得选对钩才能显示类型,则再设置如下 5.完成,测 ...

  4. 修改 Android 5.1 默认设置

    应用能够配置Android系统的各种设置,这些设置的默认值都是由frameworks中的SettingsProvider从数据库中读取的frameworks/base/packages/Setting ...

  5. 用户设置及用户默认设置

    1.创建 其中,Root.plist中为设置 2.读取应用中的设置 3.在应用中修改默认设置 4.注册默认值 5.保证设置有效(我们注册所有控制器,以便接收从暂停执行状态唤醒的应用发送出来的通知) 每 ...

  6. 如何在Windows 10中将触摸板重置为默认设置

    If you accidentally change a touchpad setting, if your touchpad is acting up, or if you want a fresh ...

  7. JVM中可生成的最大Thread数量

    最近想测试下Openfire下的最大并发数,需要开大量线程来模拟客户端.对于一个JVM实例到底能开多少个线程一直心存疑惑,所以打算实际测试下,简单google了把,找到影响线程数量的因素有下面几个: ...

  8. GDC服务器主机与证书不匹配,调用web服务soap时,错误https URL主机名与客户端信任库中服务器证书上的公用名(CN)不匹配...

    嘿,我想用SAAJ调用soap web服务 我用野蝇10 我试图将此系统属性添加到standalone.xml,但无法工作 20: 53:08208错误[stderr](默认任务-21),原因是:ja ...

  9. 追踪JVM中的本地内存

    点击蓝色"程序猿DD"关注我 回复"资源"获取独家整理的学习资料! 转载自公众号:锅外的大佬 1.概述 有没有想过为什么Java应用程序通过众所周知的-Xms和 ...

最新文章

  1. 如何自学python爬虫-Python初学者如何从网络爬虫到机器学习?
  2. 网络接口配置-Bonding
  3. python 序列解包(解压缩)
  4. python matplotlib.pyplot 如何实时绘制三维动态窗口?(可鼠标拖动角度)
  5. java 内存屏障类型_Java内存模型精讲
  6. .net core 中间件管道底层剖析
  7. 单例模式引发的内存泄漏:_资源泄漏:救援的命令模式
  8. 【HDU - 6203】ping ping ping(lca+贪心思想,对lca排序,树状数组差分)
  9. channelsftp 上传文件为空_SpringBoot文件上传下载篇(九)
  10. axure 小程序 lib_使用maven和fat jar/war运行应用程序的对比
  11. mysql讀取sql_MySQL数据库之python json及mysql读取json文件存sql等问题
  12. Java 并发编程阅读笔记
  13. python 监视文件目录
  14. 用足球阵型告诉你,阿里云如何护航全网70%世界杯流量
  15. 重锤痛击 robocode!
  16. 智能计算之蚁群算法(ACO)介绍
  17. 渗透工具-masscan
  18. vue 倒计时 插件_vue+moment实现倒计时效果
  19. 和平精英android怎么写符号,特殊符号输入方法 和平精英iOS和安卓名字特殊符号...
  20. C语言提取字符对应的ASCAl,ascall码对照表(ASCII码表)

热门文章

  1. bmp180气压传感器工作原理_陕西压力传感器的工作原理信息推荐
  2. jsp界面自动生成文件注释_实施注释界面
  3. jboss8日志级别设置_罐中研讨会:设置JBoss BRMS全日研讨会
  4. redis开启redis_Redis聚类
  5. 引入我们全新的YouTube频道进行视频课程编程
  6. 带有Prometheus的Spring Boot和测微表第6部分:保护指标
  7. 怎样编写测试类测试分支_编写干净的测试-被认为有害的新内容
  8. 通过这5个简单的技巧减少GC开销
  9. java web 刷新_Java Web项目的保存和刷新
  10. servlet3异步_Servlet 3的异步Servlet功能