java application项目(非web项目)
改进前:
-Xms128m
-Xmx128m
-XX:NewSize=64m
-XX:PermSize=64m
-XX:+UseConcMarkSweepGC
-XX:CMSInitiatingOccupancyFraction=78
-XX:ThreadStackSize=128
-Xloggc:logs/gc.log
-Dsun.rmi
.dgc
.server
.gcInterval
=3600000
-Dsun.rmi
.dgc
.client
.gcInterval
=3600000
-Dsun.rmi
.server
.exceptionTrace
=true
问题:
- permsize 设置较小,很容易达到报警范围(0.8)
- 没有设置MaxPermSize,堆增长会带来额外压力。
- NewSize较大,old gen 剩余空间64m,一方面可能会带来old区容易增长到报警范围(监控数据显示oldgenused长期在50m左右,接近78%,容易出现full gc),另一方面也存在promontion fail风险
改进后:
-Xms128m
-Xmx128m
-Xmn24m
-XX:PermSize=80m
-XX:MaxPermSize=80m
-Xss256k
-XX:SurvivorRatio=1
-XX:MaxTenuringThreshold=20
-XX:+UseParNewGC
-XX:+UseConcMarkSweepGC
-XX:CMSInitiatingOccupancyFraction=75
-XX:+UseCMSCompactAtFullCollection
-XX:+CMSParallelRemarkEnabled
-XX:CMSFullGCsBeforeCompaction=2
-XX:SoftRefLRUPolicyMSPerMB=0
-XX:+PrintClassHistogram
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-XX:+PrintHeapAtGC
-Xloggc:logs/gc.log
-Dsun.rmi
.dgc
.server
.gcInterval
=3600000
-Dsun.rmi
.dgc
.client
.gcInterval
=3600000
-Dsun.rmi
.server
.exceptionTrace
=true
修改点:
- PermSize与MaxPermSize都设置为80,一方面避免non heap warn(报警阀值0.8 非对内存一般占用到60M以内),一方面避免堆伸缩带来的压力
- 通过设置Xmn=24M及SurvivorRatio=1 使得Eden区=from space=to
space=8M,降低了Eden区大小,降低YGC的时间(降低到3-4ms左右),同时通过设MaxTenuringThreshold=20,使得
old gen的增长很缓慢。带来的问题是YGC的次数明显提高了很多。
- 其他参数优化 修改后带来的好处见JVM参数设置
再次改进后
-Xms128m
-Xmx128m
-Xmn36m
-XX:PermSize=80m
-XX:MaxPermSize=80m
-Xss256k
-XX:SurvivorRatio=1
-XX:MaxTenuringThreshold=20
-XX:+UseParNewGC
-XX:+UseConcMarkSweepGC
-XX:CMSInitiatingOccupancyFraction=73
-XX:+UseCMSCompactAtFullCollection
-XX:+CMSParallelRemarkEnabled
-XX:CMSFullGCsBeforeCompaction=2
-XX:SoftRefLRUPolicyMSPerMB=0
-XX:+PrintClassHistogram
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-XX:+PrintHeapAtGC
-Xloggc:logs/gc.log
-Dsun.rmi
.dgc
.server
.gcInterval
=3600000
-Dsun.rmi
.dgc
.client
.gcInterval
=3600000
-Dsun.rmi
.server
.exceptionTrace
=true
修改点:
在上面的基础上调整Xmn大小到36M,设置CMSInitiatingOccupancyFraction=73。
Dden区与Survivor区大小都增加到12M,通过
CMSInitiatingOccupancyFraction计算公式
,
计算得出value为73是,可以避免promotion faild问题,同时满足堆内存监控报警值在80%:内存大小128M*80%=102.4M
102.4M-36M=66.4M(老生代达到此值报警) 老生代达到67.15M(92M*0.73)将发生Full
GC,所以在老生代大小达到66.4M时也就是WARN报警时将很有可能出现Full GC。
增大了Eden和Survivor区的值,会减小YGC的次数,但由于空间变大理论上也会相应的增加YGC的时间,不过由于新生代本身就很小(才36M)这点儿变化可以忽略掉。实际的监控值显示YGC的时间在4-5ms之间。是可以接受范围。
SurvivorRatio 这个值还得在仔细考虑下,有待优化中
网上某个牛人的配置 :每天几百万pv一点问题都没有,网站没有停顿
$JAVA_ARGS
.=
"
-Dresin.home
=$SERVER_ROOT
-server
-Xms6000M
-Xmx6000M
-Xmn500M
-XX:PermSize=500M
-XX:MaxPermSize=500M
-XX:SurvivorRatio=65536
-XX:MaxTenuringThreshold=0
-Xnoclassgc
-XX:+DisableExplicitGC
-XX:+UseParNewGC
-XX:+UseConcMarkSweepGC
-XX:+UseCMSCompactAtFullCollection
-XX:CMSFullGCsBeforeCompaction=0
-XX:+CMSClassUnloadingEnabled
-XX:-CMSParallelRemarkEnabled
-XX:CMSInitiatingOccupancyFraction=90
-XX:SoftRefLRUPolicyMSPerMB=0
-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秒;
-Xmx4000M
-Xms4000M
-Xmn600M
-XX:PermSize=500M
-XX:MaxPermSize=500M
-Xss256K
-XX:+DisableExplicitGC
-XX:SurvivorRatio=1
-XX:+UseConcMarkSweepGC
-XX:+UseParNewGC
-XX:+CMSParallelRemarkEnabled
-XX:+UseCMSCompactAtFullCollection
-XX:CMSFullGCsBeforeCompaction=0
-XX:+CMSClassUnloadingEnabled
-XX:LargePageSizeInBytes=128M
-XX:+UseFastAccessorMethods
-XX:+UseCMSInitiatingOccupancyOnly
-XX:CMSInitiatingOccupancyFraction=80
-XX:SoftRefLRUPolicyMSPerMB=0
-XX:+PrintClassHistogram
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-XX:+PrintHeapAtGC
-Xloggc:log/gc.log
改进方案:
上面方法不太好,因为没有用到救助空间,所以年老代容易满,CMS执行会比较频繁。我改善了一下,还是用救助空间,但是把救助空间加大,这样也不会有promotion failed。
具
体操作上,32位Linux和64位Linux好像不一样,64位系统似乎只要配置MaxTenuringThreshold参数,CMS还是有暂停。为
了解决暂停问题和promotion failed问题,最后我设置-XX:SurvivorRatio=1
,并把MaxTenuringThreshold去掉,这样即没有暂停又不会有promotoin
failed,而且更重要的是,年老代和永久代上升非常慢(因为好多对象到不了年老代就被回收了),所以CMS执行频率非常低,好几个小时才执行一次,这
样,服务器都不用重启了。
某网友:
$JAVA_ARGS
.=
"
-Dresin.home
=$SERVER_ROOT
-server
-Xmx3000M
-Xms3000M
-Xmn600M
-XX:PermSize=500M
-XX:MaxPermSize=500M
-Xss256K
-XX:+DisableExplicitGC
-XX:SurvivorRatio=1
-XX:+UseConcMarkSweepGC
-XX:+UseParNewGC
-XX:+CMSParallelRemarkEnabled
-XX:+UseCMSCompactAtFullCollection
-XX:CMSFullGCsBeforeCompaction=0
-XX:+CMSClassUnloadingEnabled
-XX:LargePageSizeInBytes=128M
-XX:+UseFastAccessorMethods
-XX:+UseCMSInitiatingOccupancyOnly
-XX:CMSInitiatingOccupancyFraction=70
-XX:SoftRefLRUPolicyMSPerMB=0
-XX:+PrintClassHistogram
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-XX:+PrintHeapAtGC
-Xloggc:log/gc.log
";
64位jdk参考设置,年老代涨得很慢,CMS执行频率变小,CMS没有停滞,也不会有promotion failed问题,内存回收得很干净
参考:
分享到:
相关推荐
以上知识与"生产环境jvm调优的实例代码-jvm.zip"中提供的资源相结合,将帮助你更有效地实践JVM调优,解决生产环境中的性能问题。记得在实际操作中,应根据应用的具体情况进行调整,同时进行充分的测试,确保调优措施...
此外,JVM参数的设置也至关重要,例如堆大小、新生代和老年代的比例、GC策略等,都需要根据应用特性和资源状况进行合理配置。 总的来说,IBM JVM的深入理解和优化是提升Java应用性能的关键。这个压缩包中的IBM JVM....
最后,手册强调,在生产环境中应用JVM参数调整时需要谨慎。因为JVM内部经过大量的实践和优化,一般情况下我们只需要通过工具排查问题,而不轻易调整JVM参数。除非必要,否则不应随意更改JVM的默认行为,以免引入新的...
【JVM参数配置详解】 Java Virtual Machine (JVM) 是Java程序的核心组成部分,它负责解析和执行Java程序的字节码。...在实践中,应结合监控工具持续观察和分析JVM的运行状态,以便及时发现问题并做出相应的优化策略。
本文将探讨如何在Windows环境下通过简单的命令行工具来监控JVM实例的数量,以及如何进行线程测试,特别是在单例模式下的JVM实例验证。 首先,了解如何监控JVM实例数量。在Windows操作系统中,我们可以使用`jps`命令...
本文将基于提供的文件内容,深入解析Linux环境下JVM的基本参数设置方法及原理。 #### 一、内存参数设置 在JVM参数配置中,内存管理是最为关键的部分之一。下面我们将详细解释几个重要的内存相关参数及其作用: 1....
2. **连接本地JVM**:启动后,jconsole会自动检测并列出当前系统上的所有JVM实例。 3. **连接远程JVM**:如果需要监控远程JVM,则需要在远程JVM上启动相应的服务,并在jconsole中输入远程JVM的服务地址进行连接。 #...
- **-Dcom.ibm.tools.attach.enable**: 允许应用程序使用Attach API连接到正在运行的JVM实例。 - **-Dcom.ibm.UseCLDR16**: 控制是否使用最新的CLDR(Common Locale Data Repository)版本16。 - **-Dcom.ibm.xtq...
Java虚拟机(JVM)是运行Java应用程序的核心组件,它提供了一个可移植、安全且高性能的环境。本文将深入探讨JVM的内部架构及其各个组成部分的功能。 #### 二、Java虚拟机的内部组件 Java虚拟机的内部组件可以分为两大...
### JVM实战-JVM类加载机制案例分析 #### 实验背景与目标 本次实验的主要目的是深入理解Java虚拟机(JVM)中的类加载机制。通过实践操作,掌握类的加载、连接与初始化过程,了解不同类型的类加载器及其工作原理,...
在本文中,我们将详细探讨如何使用VisualVM来监控本地和远程的JVM实例。 1. **VisualVM概述** VisualVM是一个跨平台的工具,支持Windows、Linux和macOS等操作系统。它提供了丰富的图形界面,用户可以通过直观的...
【Jvm 内存分析文档】 Java 虚拟机(JVM)是Java程序的核心运行环境,它负责管理和执行字节码。JVM内存管理主要包括内存结构、内存分配以及垃圾回收(GC)等方面。了解这些知识对于优化Java应用程序的性能至关重要...
根据JVM参数的设置,堆可以被划分为新生代和老年代,新生代又进一步细分为Eden区和两个Survivor区。5、方法区:也称为永久代,存储类的信息、常量、静态变量等,JDK 8之后被元空间(Metaspace)取代,元空间使用的是...
这些参数控制着 JVM 中的堆内存和非堆内存的分配。 Xms:指定 JVM 初始分配的堆内存。默认值是物理内存的 1/64。 Xmx:指定 JVM 最大允许分配的堆内存。默认值是物理内存的 1/4。 PermSize:指定 JVM 初始分配的...
在Java世界中,JVM(Java虚拟机)是运行所有Java应用程序的基础,它为每个应用程序提供了一个独立的运行环境。Spring Boot是一个简化Spring应用开发的框架,它通过提供默认配置和starter项目,使得构建微服务变得...
Java虚拟机(JVM)是Java程序运行的基础,它负责解释和执行字节码,为应用程序提供运行环境。在开发大型或复杂的Java项目时,尤其是使用集成开发环境(IDE)如MyEclipse时,可能会遇到内存不足的问题。这通常与JVM的...
JVM性能调优 JVM(Java Virtual Machine...JVM性能调优需要了解JVM基础知识、JVM参数调优、堆空间内存分配、垃圾收集等知识点,并结合实际应用中的需求和限制,选择合适的JVM参数配置和垃圾收集算法,以提高JVM性能。
- Java中创建线程有三种方式:直接继承`java.lang.Thread`类,实现`java.lang.Runnable`接口,或者使用`java.lang.Thread`的构造函数传入`Runnable`实例。 - 线程有自己的工作内存,存储从主内存拷贝的变量副本。...