JVM参数调优是个很头痛的问题,设置的不好,JVM不断执行Full GC,导致整个系统变得很慢,网站停滞时间能达10秒以上,这种情况如果没隔几分钟就来一次,自己都受不了。这种停滞在测试的时候看不出来,只有网站pv达到数十万/天的时候问题就暴露出来了。
要想配置好JVM参数,需要对年轻代、年老代、救助空间和永久代有一定了解,还要了解jvm内存管理逻辑,最终还要根据自己的应用来做调整。关于JVM参数上网一搜就能搜出一大把,也有很多提供实践的例子,我也按照各种例子测试过,最终还是会出现问题。
Xms6000M |
最小堆 |
Xmx6000M |
最大堆 |
Xmn500M |
年轻代 |
XX:PermSize=500M |
持久代 |
XX:MaxPermSize=500M |
最大持久代 |
XX:SurvivorRatio=65536 |
去掉拯救空间 |
XX:MaxTenuringThreshold=0 |
|
Xnoclassgc |
类不GC |
XX:+DisableExplicitGC |
关闭显示GC |
XX:+UseParNewGC |
年轻代采用并行GC,16默认 |
XX:+UseConcMarkSweepGC |
老年采用并发GC |
XX:+UseCMSCompactAtFullCollection |
FullGC后对内存进行整理压缩 |
XX:CMSFullGCsBeforeCompaction=0 |
表示执行N次FullGC后执行内存压缩 |
XX:+CMSClassUnloadingEnabled |
类卸载 |
XX: CMSParallelRemarkEnabled |
在-XX:+UseParNewGC下,使用并行mark,点少mark时间 |
XX:CMSInitiatingOccupancyFraction=90 |
表示年老代占到约90%时就开始执行CMS |
XX:SoftRefLRUPolicyMSPerMB=0 |
“软引用”的对象在最后一次被访问后能存活0毫秒(默认为1秒) |
XX:+PrintClassHistogram |
|
XX:+PrintGCDetails |
|
XX:+PrintGCTimeStamps |
|
XX:+PrintHeapAtGC |
|
Xloggc:log/gc.log "; |
|
jvm参数调优给出以下几条经验:
1. 建议用64位操作系统,Linux下64位的jdk比32位jdk要慢一些,但是吃得内存更多,吞吐量更大。
2. XMX和XMS设置一样大,MaxPermSize和MinPermSize设置一样大,这样可以减轻伸缩堆大小带来的压力。
3. 调试的时候设置一些打印参数,如-XX:+PrintClassHistogram -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC -Xloggc:log/gc.log,这样可以从gc.log里看出一些端倪出来。
4. 系统停顿的时候可能是GC的问题也可能是程序的问题,多用jmap和jstack查看,或者killall -3 java,然后查看java控制台日志,能看出很多问题。
5. 仔细了解自己的应用,如果用了缓存,那么年老代应该大一些,缓存的HashMap不应该无限制长,建议采用LRU算法的Map做缓存,LRUMap的最大长度也要根据实际情况设定。
6.垃圾回收时promotion failed是个很头痛的问题,一般可能是两种原因产生,第一个原因是救助空间不够,救助空间里的对象还不应该被移动到年老代,但年轻代又有很多对象需要放入救助空间;第二个原因是年老代没有足够的空间接纳来自年轻代的对象;这两种情况都会转向Full GC,网站停顿时间较长。第一个原因我的最终解决办法是去掉救助空间,设置-XX:SurvivorRatio=65536 -XX:MaxTenuringThreshold=0即可,第二个原因我的解决办法是设置CMSInitiatingOccupancyFraction为某个值(假设70),这样年老代空间到70%时就开始执行CMS,年老代有足够的空间接纳来自年轻代的对象。
7. 不管怎样,永久代还是会逐渐变满,所以隔三差五重起java服务器是必要的,我每天都自动重起。
8.采用并发回收时,年轻代小一点,年老代要大,因为年老大用的是并发回收,即使时间长点也不会影响其他程序继续运行,网站不会停顿。
最终配置如下(系统8G内存),每天几百万pv一点问题都没有,网站没有停顿。
Xms6000M |
最小堆 |
Xmx6000M |
最大堆 |
Xmn500M |
年轻代 |
XX:PermSize=500M |
持久代 |
XX:MaxPermSize=500M |
最大持久代 |
XX:SurvivorRatio=65536 |
去掉拯救空间 |
XX:MaxTenuringThreshold=0 |
|
Xnoclassgc |
类不GC |
XX:+DisableExplicitGC |
关闭显示GC |
XX:+UseParNewGC |
年轻代采用并行GC,16默认 |
XX:+UseConcMarkSweepGC |
老年采用并发GC |
XX:+UseCMSCompactAtFullCollection |
FullGC后对内存进行整理压缩 |
XX:CMSFullGCsBeforeCompaction=0 |
表示执行N次FullGC后执行内存压缩 |
XX:+CMSClassUnloadingEnabled |
类卸载 |
XX: CMSParallelRemarkEnabled |
在-XX:+UseParNewGC下,使用并行mark,点少mark时间 |
XX:CMSInitiatingOccupancyFraction=90 |
表示年老代占到约90%时就开始执行CMS |
XX:SoftRefLRUPolicyMSPerMB=0 |
“软引用”的对象在最后一次被访问后能存活0毫秒(默认为1秒) |
XX:+PrintClassHistogram |
|
XX:+PrintGCDetails |
|
XX:+PrintGCTimeStamps |
|
XX:+PrintHeapAtGC |
|
Xloggc:log/gc.log "; |
|
说明一下, -XX:SurvivorRatio=65536 -XX:MaxTenuringThreshold=0就是去掉了救助空间;
-Xnoclassgc禁用类垃圾回收,性能会高一点;
-XX:+DisableExplicitGC禁止System.gc(),免得程序员误调用gc方法影响性能;
-XX:+UseParNewGC,对年轻代采用多线程并行回收,这样收得快;
带CMS参数的都是和并发回收相关的,不明白的可以上网搜索;
CMSInitiatingOccupancyFraction,这个参数设置有很大技巧,基本上满足(Xmx-Xmn)*(100-CMSInitiatingOccupancyFraction)/100>=Xmn就不会出现promotion failed。在我的应用中Xmx是6000,Xmn是500,那么Xmx-Xmn是5500兆,也就是年老代有5500兆,CMSInitiatingOccupancyFraction=90说明年老代到90%满的时候开始执行对年老代的并发垃圾回收(CMS),这时还剩10%的空间是5500*10%=550兆,所以即使Xmn(也就是年轻代共500兆)里所有对象都搬到年老代里,550兆的空间也足够了,所以只要满足上面的公式,就不会出现垃圾回收时的promotion failed;
SoftRefLRUPolicyMSPerMB这个参数我认为可能有点用,官方解释是softly reachable objects will remain alive for some amount of time after the last time they were referenced. The default value is one second of lifetime per free megabyte in the heap,我觉得没必要等1秒;
相关推荐
### JVM指令手册知识点 #### 概述 JVM(Java虚拟机)是执行Java字节码的...JVM指令手册是Java开发者必备的参考资料之一,通过学习手册中的指令,开发者可以更好地理解Java程序的执行过程,优化代码,解决性能问题。
2. **文档**:详细说明了如何安装、配置和使用这个库,包括示例代码和API参考。 3. **测试**:测试用例,确保库的正确性和稳定性。 4. **依赖**:可能列出需要的其他Python库或Java库,以便正确运行。 5. **示例**:...
本书《Programming Concurrency on the JVM》由Venkat Subramaniam撰写,版权归属...无论是对于经验丰富的开发人员,还是正在学习并发编程的初学者,《Programming Concurrency on the JVM》都是一本不可多得的参考书。
1. JVM的历史:这部分内容通常会回顾JVM的发展历程,从最初为了跨平台运行Java程序的目的开始,介绍JVM是如何随着时间演化,适应新的技术挑战和需求的。 2. 规范组织:文档会说明其结构,通常包含目录、前言、介绍...
要说明这个问题,先要明确两点:1. 不要试图与 C 进行类比,Java 中没有指针的概念。2. 程序运行永远都是在栈中进行的,因而参数传递时,只存在传递基本类型和对象引用的问题。不会直接传对象本身。明确以上两点后。...
JVM规范并不是特定虚拟机实现的说明书,而是确保所有JVM实现保持一致性的合同文档。它定义了JVM的概念模型,即一个抽象的计算机,规定了其运行时环境的基本结构和行为,包括类格式、数据类型、指令集、异常处理、...
JVM垃圾回收算法工作原理详解主要介绍了JVM的垃圾回收算法如何判断对象是否可以被回收,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值。 JVM垃圾回收算法工作原理可以分为两种方法...
就可以实现远程监控,和用户管理模块,动态定时任务支付windows服务器和Linux服务监控,Mac还未测试 应该也支持参考项目地址:项目框架SpringBoot 2.0.3.RELEASEmybatis-plus 3.6MySqlJdk1.8目录说明actuator-...
4. **验证安装**:打开命令提示符,输入`java -version`和`javac -version`,如果显示正确版本信息,说明安装成功。 对于开发者来说,了解不同版本的JDK特性及其安装配置是至关重要的,这有助于选择最适合项目需求...
### Java习题参考答案知识点解析 #### 一、Java的特点 **1.1 简单性** - **特点说明**: Java设计时考虑到了初学者的易学性,以及对系统资源的需求较低。 - **应用实例**: 开发者能够快速上手并构建简单的应用程序...
要说明这个问题,先要明确两点:1. 不要试图与C进行类比,Java中没有指针的概念;2. 程序运行永久都是在栈中进行的,因而参数传递时,只存在传递基本类型和对象引用的问题。不会挺直传对象本身。明确以上两点后。...
以下是对标题和描述中提及的知识点的详细说明: 1. **Java多线程并发**:在Java中,多线程并发是性能优化的关键。它允许程序同时执行多个任务,提高系统的资源利用率。Java提供了多种创建和管理线程的方式,如...
此外,提到Java对于其他编程语言的继承和发扬,也说明了Java语言具有强大的后发优势和生态系统的兼容性。Java语言的设计者们既保留了C++的强大功能,同时又解决了C++中较为复杂难以管理的问题,使得Java成为了一个...
这个名为“Java及Web开发参考手册大全”的压缩包文件很可能包含了一系列有关Java编程语言和Web开发的详细指南、教程以及最佳实践文档。以下是对这些主题的一些核心知识点的详细说明: ### Java编程语言 #### 基本...
《深入Java虚拟机》是一本深受Java开发者喜爱的经典著作,对于想要提升Java开发技能,尤其是对Java虚拟机(JVM)工作原理有深入了解的程序员来说,这本书是不可或缺的参考资料。JVM是Java语言的核心组成部分,它负责...