热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

jvm的代码缓存耗尽导致性能下降

在没遇到这个问题之前,我对JVM的解释模式与编译模式的代码性能相差有多大,是没有感觉的,只是觉得编译模式会比解释模式性能好那么一点点吧。但是经历过这次以后,让我对JVM的即时编译产生了兴趣。先来看

  在没遇到这个问题之前,我对JVM的解释模式与编译模式的代码性能相差有多大,是没有感觉的,只是觉得编译模式会比解释模式性能好那么一点点吧。

但是经历过这次以后,让我对JVM的即时编译产生了兴趣。先来看看这个问题的背景:

  大概是4年前,我的团队里有一个PM找我说他们遇到一个很奇怪的问题,在性能测试的时候,有几个不同的测试场景混合在一起进行压力测试,有时会出现测试几十几分钟以后性能会下降的很厉害,一旦出现性能下降以后,性能再也回不到刚开始测试的水平。奇怪的是:它不是必现的,而且如果只是某1个或者2个场景一起测试的话,不会出现。

  因为不是网上问题,所以我有时间坐下来好好分析,先安排老思路排查,按我遇到的经验一般性能瓶颈是某些资源遇到了瓶颈,这些瓶颈可以是磁盘IO、网络IO、CPU、内存等,然后使用相应的Linux命令一一排查。在排查到CPU的时候,发现CPU比较高,然后使用jstack多次取堆栈进行分析,但是发现每次堆栈的栈顶都不太一样,但是从栈顶再往下看,能看到都是停留在我们使用的一个商用软件Volantis MCS的堆栈上。Volantis MCS即Volantis Multi Channel Server,它的作用是使用某种开发语言开发一个页面,在用户通过手机访问时会根据用户的手机的User-Agent自动转换成最适合手机展示的xhtml页面,就是我们常说的终端适配了。

  它与我们以往的不一样的是以前出现的CPU高一般堆栈都是集中在某一个或者几个方法上,而这次是分散在很多处,有点犯难了。

  由于是商用软件,没有源代码,我只能把取到一些典型的堆栈记下来,然后反编译代码,看到经常在jstack上处于Runnable的栈顶的代码并不是很复杂的逻辑,只有一些基本的字符串、+-*/这样的运算。因为性能压测tps比较高,直接使用JProfiler工具的话,性能是压不上去的,只能拿出我的杀手锏了: 把class反编译以后,自己加了一些统计性能的代码,并定期的打印出来。虽然方法有点土,但是直接有效。

  打印出统计日志以后,就发现问题所在了,同样没有任何IO操作的方法,在出现问题前调用一次在3~5ms,而出现问题以后这个方法平均时长为20~30ms。难道是输入不一样吗?随后又增加日志把输入也打印出来,发现完全一样。

  同样的输入,同样的代码,竟然性能相差这么大,难道是机器上有其它进程(线程性能影响),排查了也没有呀。

  这时突然灵光一现,是不是因为这段代码在一定情况下没有编译成本地代码,而是在解释模式下运行的?是不是编译代码时也有缓存大小,在网上查了一下我所用的JDK版本的默认的代码缓存是64M,在官方找到了对应版本的配置,并根据网上的信息如果发生这种问题,会在gc日志会打印一句warning,具体的warning是什么忘记了。反正我们的机器的内存配置一般至少都是32G,代码缓存配置为128M也不为过,配置了以后不论怎么测试都OK了.

   回过头了想想为什么会有时出现有时没有?猜测原因大概是这样的,因为我们应用代码量非常大,使用了很多第三方软件,特别是Volantis MCS这样非常耗CPU的组件执行的频率如此之频繁,在某一种场景下,如果先测试某个流程会导致那个流程中大量的代码被转换成本地代码,然后再执行这些非常频繁的代码的时候代码的缓存因为耗尽了,就只能采用解释的方式执行。

  事情到这里其它我最感兴趣的地方才刚开始:

  1、解释模式与编译模式性能究竟相差多少?

  2、为什么编译以后的代码性能这么高?

  第一个问题我做了测试,把JVM的配置修改为纯解释模式,原来几分钟启动的应用,等了有20分钟左右还没有完全启动起来,要知道我们用的服务器一般至少都是4核心的。第二个问题,下载了openjdk的代码,看了x86的c++的代码,发现太复杂了,当时放弃继续研究。直到去年的时候,我离开华为的时候有了一些自己的时间,自己买了一本《Hotspot实战》并在iteye上有一个高级虚拟机的组的一些前阿里大神的一些文章,结合openjdk 8的代码,才慢慢对编译的原理有些感觉。为什么性能相差这么大,我的理解解释模式采用套用代码调用的模板,每一个指令选择一个template,把执行的template的汇编代码打印出来,可以看出来一个很简单的指令都会生成一堆指令。而编译模式有C1和C2 2层优化(http://hllvm.group.iteye.com/group/topic/39493),JVM先把汇编指令转换成一种中间的代码格式ad,再采用传统的编译器的优化优化技术,这些优化技术是集国外的各大神的技术精髓,所以它重新生成的代码比你手工写的代码质量高就一点不奇怪了。

  随着逐步深入,发现原来JVM的GC又是一块宝藏。话题有点扯远了,发现自己懂的太少了,JVM里面好玩的东西太多了,学习中...

 


推荐阅读
  • Nginx使用AWStats日志分析的步骤及注意事项
    本文介绍了在Centos7操作系统上使用Nginx和AWStats进行日志分析的步骤和注意事项。通过AWStats可以统计网站的访问量、IP地址、操作系统、浏览器等信息,并提供精确到每月、每日、每小时的数据。在部署AWStats之前需要确认服务器上已经安装了Perl环境,并进行DNS解析。 ... [详细]
  • CentOS 7部署KVM虚拟化环境之一架构介绍
    本文介绍了CentOS 7部署KVM虚拟化环境的架构,详细解释了虚拟化技术的概念和原理,包括全虚拟化和半虚拟化。同时介绍了虚拟机的概念和虚拟化软件的作用。 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • 开发笔记:Python之路第一篇:初识Python
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了Python之路第一篇:初识Python相关的知识,希望对你有一定的参考价值。Python简介& ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • Servlet多用户登录时HttpSession会话信息覆盖问题的解决方案
    本文讨论了在Servlet多用户登录时可能出现的HttpSession会话信息覆盖问题,并提供了解决方案。通过分析JSESSIONID的作用机制和编码方式,我们可以得出每个HttpSession对象都是通过客户端发送的唯一JSESSIONID来识别的,因此无需担心会话信息被覆盖的问题。需要注意的是,本文讨论的是多个客户端级别上的多用户登录,而非同一个浏览器级别上的多用户登录。 ... [详细]
  • jvm内存区域与溢出为什么学习jvm木板原理,最短的一块板决定一个水的深度,当一个系统垃圾收集成为瓶颈的时候,那么就需要你对jvm的了解掌握。当一个系统出现内存溢出,内存泄露的时候 ... [详细]
  • Android系统启动过程分析一、Android平台架构首先贴一张Android系统架构图方便理解整个Android架构,这可以让我们从整体上对整个启动流程有个大概认知。可以看出整 ... [详细]
  • 压力测试工具  ab
    ab是Apache自带的一个压力测试工具,命令行,是ApacheBench命令的缩写。ab的原理:ab命令会创建多个并发访问线程ÿ ... [详细]
  • 压力测试_单节点数据库的压力测试
    mysqlslap是mysql自带的基准测试工具,优点:查询数据,语法简单 ... [详细]
  • Centos7.6安装Gitlab教程及注意事项
    本文介绍了在Centos7.6系统下安装Gitlab的详细教程,并提供了一些注意事项。教程包括查看系统版本、安装必要的软件包、配置防火墙等步骤。同时,还强调了使用阿里云服务器时的特殊配置需求,以及建议至少4GB的可用RAM来运行GitLab。 ... [详细]
  • 本文介绍了在Windows环境下如何配置php+apache环境,包括下载php7和apache2.4、安装vc2015运行时环境、启动php7和apache2.4等步骤。希望对需要搭建php7环境的读者有一定的参考价值。摘要长度为169字。 ... [详细]
  • C++字符字符串处理及字符集编码方案
    本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]
author-avatar
AAAAaaaa叶子
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有