这篇文章是关于最近一次性能调优的经历。跟往常一样,开始的时候总会有一些模糊的征兆。这次的现象看起来是”应用程序运行缓慢,但是我们无法获取到对应的源代码。我们该如何来解决这个问题“。
仔细观察下这个应用会发现它运行着一些批量任务。分析下性能相关的指标会发现它在运行某个特定任务的时候花费的时间太长了。进一步分析我得出了一个可量化的优化目标。我需要将这个任务预分配内存所占用的时间减少两分钟。
这个出问题的应用程序只是个非常无辜的小jar包而已。幸运的是,我对它进行了压测。
打开GC日志开关(-XX:+PrintGCTimeStamps -Xloggc:/path-to/gc.log -XX:+PrintGCDetails)后运行这个应用程序,并分析日志,很快你就会发现第一个要优化的目标。GC暂停时间加起来花了有3分半钟,这说明这块是一个优化的机会。
像这种情况一般有好几种解决办法 ,下面几种是比较简单和直接的:
修改堆的大小
调整GC算法
调整内存堆各区域的大小比例。
我选择了修改堆大小的方式。这并不是我运气好而蒙对的,是因为我最近学习了一些关于存活数据集大小和推荐的堆大小关系的东西。从GC日志中我注意到存活数据集大概是240M。因此根据我最近所了解到的知识来看,应用的最佳堆大小大概是在720M到960M之间。
不过我发现现在配置的堆大小只有300M。调整了下参数后我重新运行了下该测试用例 ,结果如下:
堆大小 |
总的GC暂停时间 | 吞吐量 |
300m | 207.48s | 92.25% |
384m | 54.13s | 97.97% |
720m | 20.52s | 99.11% |
1,440m | *11.37s | *99.55% |
号表示没有出现Full GC。
如果你光看这个结果的话可能会认为结论是” 越大越好“。如果你只看这个毫秒值的话,你这么想也是对的。但如果成功的指标中有一项是和钱有关的话,就不那么容易了。成百上千台机器上进行大规模部署的话,你这么搞 ,到时光电费单就能吓你一跳。
除此之外,这篇文章也是性能调优课程上的一个用例。如果你有一个可测量的目标并且你可以去测量它的结果而不是去猜测,那么你就已经成功了。如果我没有一个明确的目标或者没法进行压测的话,可能我现在还在东调整下西调整下那么瞎捣鼓。
原创文章转载请注明出处:
http://it.deepinmind.com
英文原文链接
分享到:
相关推荐
这不仅涉及到程序设计的层面,还包括对JVM内存模型的深入理解和灵活运用。通过上述的分析和总结,我们可以得出,JVM调优是一个涉及多方面知识的复杂过程,需要开发者具备扎实的理论基础和丰富的实践经验。
字节码是一种平台无关的中间表示,使得Java具备“一次编写,到处运行”的特性。在运行时,JVM会加载这些字节码文件,进行链接和初始化,最后执行。 2. **JVM内存分代**: 为了优化垃圾回收(GC)效率,JVM将内存...
JVM在运行时将字节码转换为特定平台的机器码,使得Java程序能够“一次编写,到处运行”。 类加载器(Class Loader) 类加载器负责将.class文件加载到JVM内存中。Java的类加载机制是动态的,它支持类的懒加载(Lazy...
本文将分享一个基于旧版环境(Dell E5410,Intel i3 CPU M 370,2GB内存,32位Windows XP,Java HotSpot Client VM,Eclipse 4.2.0)的JVM调优实战案例,尽管硬件和软件版本已过时,但调优的基本思路和方法仍然具有...
##### 1.1 JVM内存结构 JVM(Java虚拟机)内存模型主要包括堆内存(Heap)、方法区(Method Area)、程序计数器(Program Counter Register)、虚拟机栈(Virtual Machine Stack)和本地方法栈(Native Method ...
总之,Java垃圾收集调优涉及到JVM内存的合理分配、垃圾收集策略的选择以及各种JVM参数的调整。通过对这些参数的精确控制,可以优化Tomcat的性能,降低内存使用,减少垃圾收集对应用程序的负面影响,从而提供更稳定的...
JVM使得Java具有“一次编写,到处运行”的特性,通过解释和编译Java字节码来执行程序。在这个JVM分享中,我们主要探讨的是JVM的基础知识,这对于想要深入理解Java底层机制的人来说是非常宝贵的资料。 首先,JVM的...
- **复制算法**:将可用内存按容量划分为大小相等的两块,每次只使用其中的一块,当这一块的内存用完了,就将还存活的对象复制到另一块上面,然后再把已使用过的内存空间一次清理掉。 - **标记-整理算法**:标记...
1. **关闭自动构建**:在大项目中,关闭自动构建可以避免每次保存时的长时间等待,只在运行前手动构建一次即可。 2. **关闭拼写检查**:减少不必要的后台处理,节省系统资源。 3. **禁用SaveAction**:避免在保存...
JVM的设计目标是实现一次编写,到处运行,通过动态编译和内存管理机制来提高性能。 2. **类加载机制**:JVM将类加载分为加载、验证、准备、解析和初始化五个阶段。类加载器是这个过程的核心,包括启动类加载器、...
大多数对象都在Eden区中创建,经过第一次GC后,存活的对象会被移动到Survivor区。如果Survivor空间不足,一些对象会直接晋升到老年代。通过调整年轻代的大小,我们可以控制对象的生命周期,减少Full GC的发生,从而...
【描述】提到的"JVM面试题PDD 下载"暗示了这是一个包含JVM相关面试问题的资源,可能是某次在线分享或者论坛的下载链接,用于帮助准备Java开发者面试。 【标签】"java"明确了这个话题与Java编程语言紧密相关,而JVM...
#### 一、JVM基础知识 ##### 1.1 JVM概念 Java虚拟机(Java Virtual Machine,简称JVM)是运行Java字节码的虚拟机环境。它为Java程序提供了一个独立于硬件平台的抽象计算机环境,使得Java程序可以在任何安装了兼容...
它负责解析和执行字节码,提供了一个跨平台的运行环境,使得Java程序能在任何安装了JVM的设备上运行,实现了“一次编写,到处运行”的目标。深入理解JVM对于优化Java应用性能、解决内存问题以及提高代码效率至关重要...
### 性能调优方案Arthus:一次真实的性能调优实践与探索 #### 一、性能调优的必要性及难点 **1.1 性能满足业务需求** 随着互联网技术的发展,用户对系统的响应速度、稳定性等性能指标提出了更高的要求。例如,在...
10. **JVM内存溢出问题**:常见的有堆溢出(OOM: OutOfMemoryError - heap space)、 PermGen/元空间溢出、方法区溢出等,需要合理设置JVM参数并优化代码以避免。 通过掌握以上知识点,Java开发者不仅可以编写高...
此外,面试者还被问及如何在线上环境中分析GC问题以及JVM的调优方法,包括1.7和1.8版本中JVM内存结构的区别,以及Full GC是否会回收Metaspace空间内存。 数据库方面,面试者遇到了关于锁等待和分布式事务的问题。...
为了解决内存溢出问题,开发者需要调整JVM的内存配置,比如增大堆大小,或者调整新生代和老年代的比例,以适应应用的内存需求。此外,使用内存分析工具(如VisualVM或JProfiler)可以帮助识别内存泄漏的具体对象和...
通过深入了解JVM的基本原理、内存管理机制以及运行时性能调优方法,可以有效地提高Java应用程序的性能。演讲者李镭结合自己丰富的实践经验,分享了如何在WebSphere环境下高效地利用JVM,这对于希望提升Java应用程序...
它负责执行字节码,提供跨平台的兼容性,是Java能够"一次编译,到处运行"的关键所在。 内存区域:JVM的内存区域包括程序计数器、虚拟机栈、本地方法栈、堆和方法区。每个线程有其私有的程序计数器、虚拟机栈和本地...