JVM内存调优
记一次JVMFullGC(MetadataGCThreshold)调优经历
记⼀次JVMFullGC(MetadataGCThreshold)调优经历记⼀次JVM Full GC (Metadata GC Threshold)调优经历⼀、背景:线上服务器内存使⽤超过90%,分析上⾯部署的各个服务的GC⽇志,发现有⼀个服务的JVM内存分配过⼤,使⽤率较低,有调优的空间,可以在不迁移服务或者不升级服务器配置的情况下,降低服务器内存占⽤。
JVM推荐配置原则:应⽤程序运⾏时,计算⽼年代存活对象的占⽤空间⼤⼩X。
程序整个堆⼤⼩(Xmx和Xms)设置为X的3 ~ 4倍;永久代PermSize和MaxPermSize设置为X的1.2 ~ 1.5倍。
年轻代Xmn的设置为X的1 ~ 1.5倍。
⽼年代内存⼤⼩设置为X的2 ~ 3倍。
JDK官⽅建议年轻代占整个堆⼤⼩空间的3/8左右。
完成⼀次Full GC后,应该释放出70%的堆空间(30%的空间仍然占⽤)。
观察线上发现2G的堆内存,Full GC之后的活跃对象才占⽤60M。
按照推荐设置JVM内存只需要给⼏百M就好了。
所以决定改成1G,既能够降低服务器内存占⽤,也预留了⾜够的业务增长空间。
在这个过程中,发现如下⼏个问题:GC⽇志没有时间显⽰,看起来很不⽅便GC⽇志没有滚动,时间久了,⽇志⽂件较⼤GC⽇志中存在⼤量Full GC (Metadata GC Threshold)显然第三个问题最为严重。
我们知道,元数据区主要是⽤来存储类的元数据的。
⼀般来讲,类加载完成之后,⼤⼩应该是⽐较稳定的,不会有太⼤变动。
所以可以判断,这么频繁的Full GC (Metadata GC Threshold),肯定是哪⾥出问题了。
但是我们⼀步⼀步来解决问题,⽽且GC⽇志不够详细也影响我们定位问题。
⼆、优化GC⽇志打印⾸先复习⼀下JVM的GC⽇志打印的启动参数。
详见-verbose:gc同-XX:+PrintGC-XX:+PrintGC最简单的 GC 参数会打印 GC 前后堆空间使⽤情况以及 GC 花费的时间-XX:+PrintGCDetails打印GC的详细信息,会打印 youngGC FullGC前后堆【新⽣代,⽼年代,永久区】的使⽤情况以及 GC 时⽤户态 CPU 耗时及系统CPU 耗时及 GC 实际经历的时间-XX:+PrintGCTimeStamps打印CG发⽣的时间戳,从应⽤启动开始累计的时间戳-XX:+PrintGCDateStamps打印GC发⽣的时刻,所处⽇期时间信息-Xloggc:gc.log指定GC log的位置,以⽂件输出-XX:+PrintHeapAtGC每⼀次GC前和GC后,都打印堆信息。
JVM调优总结-Xms-Xmx-Xmn-Xss
JVM调优总结-Xms-Xmx-Xmn-Xssjava启动参数共分为三类;其⼀是标准参数(-),所有的JVM实现都必须实现这些参数的功能,⽽且向后兼容;其⼆是⾮标准参数(-X),默认jvm实现这些参数的功能,但是并不保证所有jvm实现都满⾜,且不保证向后兼容;其三是⾮Stable参数(-XX),此类参数各个jvm实现会有所不同,将来可能会随时取消,需要慎重使⽤;标准参数中⽐较有⽤的:verbose-verbose:class输出jvm载⼊类的相关信息,当jvm报告说找不到类或者类冲突时可此进⾏诊断。
-verbose:gc输出每次GC的相关情况。
-verbose:jni输出native⽅法调⽤的相关情况,⼀般⽤于诊断jni调⽤错误信息。
⾮标准参数⼜称为扩展参数⼀般⽤到最多的是-Xms512m 设置JVM促使内存为512m。
此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。
-Xmx512m ,设置JVM最⼤可⽤内存为512M。
-Xmn200m:设置年轻代⼤⼩为200M。
整个堆⼤⼩=年轻代⼤⼩ + 年⽼代⼤⼩ + 持久代⼤⼩。
持久代⼀般固定⼤⼩为64m,所以增⼤年轻代后,将会减⼩年⽼代⼤⼩。
此值对系统性能影响较⼤,Sun官⽅推荐配置为整个堆的3/8。
-Xss128k:设置每个线程的堆栈⼤⼩。
JDK5.0以后每个线程堆栈⼤⼩为1M,以前每个线程堆栈⼤⼩为256K。
更具应⽤的线程所需内存⼤⼩进⾏调整。
在相同物理内存下,减⼩这个值能⽣成更多的线程。
但是操作系统对⼀个进程内的线程数还是有限制的,不能⽆限⽣成,经验值在3000~5000左右。
-Xloggc:file与-verbose:gc功能类似,只是将每次GC事件的相关情况记录到⼀个⽂件中,⽂件的位置最好在本地,以避免⽹络的潜在问题。
若与verbose命令同时出现在命令⾏中,则以-Xloggc为准。
-Xprof跟踪正运⾏的程序,并将跟踪数据在标准输出输出;适合于开发环境调试。
JVM内存设置方法
JVM内存设置方法JVM(Java虚拟机)是Java程序的运行环境,它负责执行Java字节码,并管理程序的内存。
在运行Java程序时,合理地设置JVM的内存大小是非常重要的,它会影响程序的性能和稳定性。
下面是一些关于JVM内存设置的方法和注意事项:1. 初始堆大小(-Xms)和最大堆大小(-Xmx):初始堆大小指定了JVM初始时分配的堆内存大小,最大堆大小则指定了堆内存的上限。
可以通过在启动命令中加上-Xms和-Xmx参数来设置堆内存大小,例如:```java -Xms256m -Xmx512m MyApp```这样就设置了初始堆大小为256MB,最大堆大小为512MB。
2.堆内存的大小选择:堆内存的大小应根据应用程序的需求和服务器硬件条件来选择。
如果堆内存过小,可能会导致OutOfMemoryError;如果堆内存过大,可能会导致频繁的垃圾回收,影响程序的性能。
可以通过监控JVM的堆使用情况来判断是否需要调整堆内存的大小。
可以使用JVM自带的JVisualVM工具或第三方的工具如G1GC日志分析工具进行监控。
3.堆内存的分代设置:堆内存分为新生代(Young Generation)、老年代(Old Generation)和永久代(Permanent Generation,JDK8及之前的版本)/元空间(Metaspace,JDK8及之后的版本)。
新生代用于存储新创建的对象,老年代用于存储长时间存活的对象,永久代/元空间用于存储类和方法等信息。
可以通过设置堆内存的分代比例来调整堆内存的大小,例如:```-XX:NewRatio=2```这样就将堆内存的新生代和老年代的大小比例设置为1:2、可以根据应用程序的特点和需求进行调整。
4.非堆内存的设置:非堆内存包括方法区、直接内存等。
可以通过设置参数来调整非堆内存的大小,例如:```-XX:MaxMetaspaceSize=256m```这样就设置了元空间的最大大小为256MB。
jvm xmn 设置规则
jvm xmn 设置规则JVM Xmn 设置规则。
JVM(Java虚拟机)的性能优化是Java应用程序开发中非常重要的一部分。
其中,Xmn 是 JVM 中用于设置新生代内存大小的参数。
在本文中,我们将讨论一些关于 JVM Xmn 设置的规则和最佳实践。
1. 了解 Xmn 参数。
Xmn 参数用于设置 JVM 的新生代内存大小。
新生代是 JVM内存中用于存放新创建的对象的区域。
通过设置 Xmn 参数,可以控制新生代的大小,从而影响垃圾回收的性能和效率。
2. 设置 Xmn 大小。
通常情况下,建议将 Xmn 大小设置为整个堆内存的 1/3 到1/4。
例如,如果堆内存大小为 1GB,那么可以将 Xmn 设置为256MB 到 333MB。
这样可以确保新生代内存有足够的空间来存放新创建的对象,同时也可以减少垃圾回收的频率和时间。
3. 考虑应用程序的特性。
在设置 Xmn 参数时,需要考虑应用程序的特性和内存使用情况。
一些应用程序可能会频繁地创建大量的临时对象,而另一些应用程序则可能更注重长期对象的管理。
根据应用程序的特性,可以调整 Xmn 的大小来更好地适应实际情况。
4. 监控和调优。
一旦设置了 Xmn 参数,就需要监控应用程序的内存使用情况,并根据实际情况进行调优。
可以通过监控工具来观察新生代的内存使用情况和垃圾回收的频率,从而及时调整 Xmn 的大小以获得更好的性能和效率。
总之,JVM Xmn 设置是优化 Java 应用程序性能的重要一环。
通过了解 Xmn 参数、设置合适的大小、考虑应用程序特性并进行监控和调优,可以有效地提升应用程序的性能和稳定性。
希望本文提供的规则和最佳实践能够帮助开发人员更好地进行 JVM Xmn 参数的设置和优化。
《Java性能调优指南》
《Java性能调优指南》随着互联网的飞速发展,Java作为一种重要的编程语言,被越来越广泛地应用于各个领域。
但是,Java程序的性能问题也随之出现。
如何调优Java 程序的性能,成为了每个开发人员需要解决的难题。
本文将为大家介绍Java性能调优的指南。
一、JVM参数设置JVM(Java虚拟机)参数设置是Java性能调优的关键。
JVM有众多的参数,不同的参数设置会对Java程序的性能产生不同的影响。
常用的JVM参数设置包括以下几个方面:1. 内存设置内存是Java程序的一大瓶颈。
如果内存设置不合理,会导致Java程序频繁地进行垃圾回收,造成程序的延迟和不稳定。
在设置内存参数时需要注意以下几点:- -Xmx: 最大堆内存,设置合理的最大堆内存大小可以减少JVM的垃圾回收次数,提高程序性能。
- -Xms: 初始堆内存,设置合理的初始堆内存大小可以加快程序启动时间,提高程序性能。
- -XX:NewRatio: 新生代与老年代的比例,如果设置得当,可以减少垃圾回收的次数。
通常新生代的大小为总堆容量的1\/3或1\/4,老年代的大小为总堆容量的2\/3或3\/4。
2. 垃圾回收设置垃圾回收是Java程序中必不可少的一部分。
合理的垃圾回收参数设置可以提高程序性能。
常用的垃圾回收参数设置包括以下几点:- -XX:+UseParallelGC: 使用并行GC,适用于多核CPU。
- -XX:+UseConcMarkSweepGC: 使用CMS GC,适用于大型Web应用程序。
- -XX:+UseG1GC: 使用G1 GC,适用于大内存应用程序。
3. JIT设置JIT(即时编译器)是Java程序中非常重要的一部分。
合理的JIT参数设置可以提高程序的性能。
常用的JIT参数设置包括以下几点:- -XX:+TieredCompilation: 启用分层编译,可以提高程序启动时间和性能。
- -XX:CompileThreshold: JIT编译阈值,设置JIT编译的最小方法调用次数,可以提高程序性能。
jvm常用调优参数
jvm常用调优参数
JVM是JavaVirtualMachine的缩写,是Java程序运行的核心。
JVM的调优是优化Java应用程序性能的重要一环,其中调优参数的合理设置是关键。
以下是常用的JVM调优参数:
1. -Xms:设置JVM的初始内存大小,默认为物理内存的
1/64。
2. -Xmx:设置JVM的最大内存大小,超出该内存大小后会触发垃圾回收。
3. -Xmn:设置年轻代的大小,一般设置为总内存的1/3或
1/4。
4. -XX:SurvivorRatio:设置年轻代中Eden区和Survivor区的比例,默认值为8。
5. -XX:NewRatio:设置新生代和老年代的比例,默认值为2。
6. -XX:MaxPermSize:设置永久代的大小,一般设置为
256MB。
7. -XX:+UseConcMarkSweepGC:使用CMS垃圾回收器,可以减少内存抖动。
8. -XX:+UseParallelGC:使用并行垃圾回收器,可提高垃圾回收效率。
9. -XX:+HeapDumpOnOutOfMemoryError:当JVM内存溢出时,生成堆转储文件。
10. -XX:+PrintGCDetails:打印垃圾回收的详细信息。
以上是常用的JVM调优参数,通过合理地设置参数,可以优化Java应用程序的性能。
JVM参数调优CMS垃圾收集器相关核心参数
JVM参数调优CMS垃圾收集器相关核心参数在JVM参数调优过程中,垃圾收集器的选择和参数的调整是非常重要的一部分。
众多垃圾收集器中,CMS(Concurrent Mark Sweep)是一种以低延迟为目标的垃圾收集器,在大内存应用中被广泛使用。
以下是CMS垃圾收集器相关的核心参数及其调优方法。
1. -XX:+UseConcMarkSweepGC:表示使用CMS垃圾收集器,该参数必须开启才能使用CMS。
2. -XX:+UseCMSInitiatingOccupancyOnly:表示只根据设置的阈值来触发CMS收集,而不是根据时间来触发。
可以根据业务场景和经验调整该阈值,建议范围在60-80之间。
3. -XX:CMSInitiatingOccupancyFraction:表示CMS触发垃圾收集的阈值,即老年代的占用率达到多少时触发。
默认值是92%,可以根据业务的内存使用情况进行调整。
如果CMS收集频繁而且停顿时间长,则可以适当降低该值。
4. -XX:+ParallelRefProcEnabled:表示启用并行清除引用(Parallel Ref Proc),可以加快CMS的回收速度,推荐使用。
5. -XX:CMSWaitDuration:表示CMS线程等待低级别垃圾收集器的时间,单位毫秒。
根据系统的性能和业务负载情况进行调整,如果系统压力较大,可以适当增加该值,防止CMS线程长时间等待。
6. -XX:CMSMaxAbortablePrecleanTime:表示CMS在发生冲突时放弃预清理所花费的最长时间。
默认值为5秒,如果CMS预清理时间超过该值,则会放弃预清理并尝试重新执行,并增加CMS收集的停顿时间。
7. -XX:ParallelGCThreads:表示垃圾收集的线程数目。
可以根据硬件的CPU核心数和应用的负载情况进行调整。
8. -XX:+ExplicitGCInvokesConcurrent:表示在显示调用System.gc(时,同时触发CMS的垃圾收集。
常见的jvm调优参数
常见的jvm调优参数JVM是Java虚拟机的简称,它是Java程序的运行环境。
在生产环境中,JVM调优非常重要,可以提高应用程序的性能和稳定性。
下面是常见的JVM调优参数:1. -Xms和-Xmx:设置JVM的初始堆大小和最大堆大小。
建议将这两个参数设置为相同的值,避免堆大小变化频繁导致性能问题。
2. -XX:PermSize和-XX:MaxPermSize:设置JVM的初始永久代大小和最大永久代大小。
永久代主要用于存储Java类元数据和字符串常量池等信息。
3. -XX:MaxMetaspaceSize:设置JVM的最大元空间大小。
元空间是永久代的替代品,用于存储类元数据等信息。
4. -XX:NewSize和-XX:MaxNewSize:设置年轻代的初始大小和最大大小。
年轻代主要用于存储新创建的对象。
5. -XX:SurvivorRatio:设置年轻代中Eden空间和Survivor空间的比例。
Eden空间用于存储新创建的对象,Survivor空间用于存储年轻代中经过一次垃圾回收后还存活的对象。
6. -XX:MaxTenuringThreshold:设置对象在年轻代中经过多少次垃圾回收后进入老年代。
可以根据应用程序的内存使用情况适当调整该参数。
7. -XX:ParallelGCThreads:设置并行垃圾回收线程的数量。
建议根据CPU核数适当调整该参数。
8. -XX:+UseG1GC:启用G1垃圾回收器。
G1垃圾回收器是Java 9及以后版本的默认垃圾回收器,它可以更好地处理大堆内存的应用程序。
9. -XX:+HeapDumpOnOutOfMemoryError:在JVM出现内存溢出错误时自动生成堆转储文件。
可以用于分析内存泄漏等问题。
以上是常见的JVM调优参数,通过合理地配置这些参数可以提高应用程序的性能和稳定性。
但需要注意的是,不同的应用程序可能需要不同的配置参数,需要根据实际情况进行调整。
jvm原理及性能调优
jvm原理及性能调优JVM原理及性能调优。
JVM(Java Virtual Machine)是Java虚拟机的缩写,是Java程序运行的核心组件。
它负责将Java字节码文件解释成特定平台上的机器指令。
JVM的性能对于Java应用程序的运行效率和稳定性有着至关重要的影响。
因此,了解JVM的原理并进行性能调优是非常重要的。
首先,我们来了解一下JVM的基本原理。
JVM主要由类加载器、运行时数据区、执行引擎三部分组成。
类加载器负责将class文件加载到JVM中,并对类进行初始化、连接和加载。
运行时数据区包括方法区、堆、虚拟机栈、本地方法栈和程序计数器,它们分别用于存储类的结构信息、对象实例、方法调用、本地方法和线程执行的位置。
执行引擎负责执行字节码指令,将Java程序转换成机器代码。
了解了JVM的基本原理之后,我们需要关注JVM性能调优的相关内容。
JVM 性能调优主要包括内存管理、垃圾回收、JIT编译器优化和线程管理等方面。
在内存管理方面,我们可以通过调整堆内存大小、永久代大小、新生代和老年代的比例等参数来优化内存的使用。
合理的内存分配可以减少内存碎片,提高内存使用效率。
垃圾回收是JVM性能调优的重要一环。
通过调整垃圾回收器的类型、参数和触发条件,我们可以优化垃圾回收的效率,减少应用程序的停顿时间,提高系统的吞吐量。
JIT编译器是JVM的即时编译器,它负责将热点代码编译成本地机器代码,以提高程序的执行速度。
我们可以通过调整JIT编译器的参数来优化编译效率,提高程序的性能。
线程管理也是JVM性能调优的重要内容。
合理的线程调度和线程池的使用可以提高系统的并发性能,减少线程的竞争和阻塞,提高系统的吞吐量。
除了上述内容,我们还可以通过监控工具对JVM进行性能分析,找出程序的瓶颈,并针对性地进行优化。
常用的监控工具包括JVisualVM、JConsole、JProfiler 等。
总的来说,JVM的性能调优是一个复杂而又细致的工作。
java jvm 参数 Xms Xmx Xmn Xss 调优总结【VIP专享】
java jvm 参数 -Xms -Xmx -Xmn -Xss 调优总结常见配置举例堆大小设置JVM 中最大堆大小有三方面限制:相关操作系统的数据模型(32-bt还是64-bit)限制;系统的可用虚拟内存限制;系统的可用物理内存限制.32位系统下,一般限制在1.5G~2G;64为操作系统对内存无限制.我在Windows Server 2003 系统, 3.5G物理内存,JDK5.0下测试,最大可设置为1478m.典型设置:java -Xmx3550m -Xms3550m -Xmn2g -Xss128k-Xmx3550m:设置JVM最大可用内存为3550M.-Xms3550m:设置JVM促使内存为3550m.此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存.-Xmn2g:设置年轻代大小为2G.整个堆大小=年轻代大小 + 年老代大小 + 持久代大小.持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小.此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8.-Xss128k: 设置每个线程的堆栈大小.JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K.更具应用的线程所需内存大小进行调整.在相同物理内存下,减小这个值能生成更多的线程.但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右.java -Xmx3550m -Xms3550m -Xss128k -XX:NewRatio=4 -XX:SurvivorRatio=4 -XX:MaxPermSize=16m -XX:MaxTenuringThreshold=0-XX:NewRatio=4:设置年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代).设置为4,则年轻代与年老代所占比值为1:4,年轻代占整个堆栈的1/5-XX:SurvivorRatio=4:设置年轻代中Eden区与Survivor区的大小比值.设置为4,则两个Survivor区与一个Eden区的比值为2:4,一个Survivor区占整个年轻代的1/6-XX:MaxPermSize=16m:设置持久代大小为16m.-XX:MaxTenuringThreshold=0: 设置垃圾最大年龄.如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代. 对于年老代比较多的应用,可以提高效率.如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象再年轻代的存活时间,增加在年轻代即被回收的概论.回收器选择JVM给了三种选择:串行收集器,并行收集器,并发收集器,但是串行收集器只适用于小数据量的情况,所以这里的选择主要针对并行收集器和并发收集器.默认情况下,JDK5.0以前都是使用串行收集器,如果想使用其他收集器需要在启动时加入相应参数.JDK5.0以后,JVM会根据当前系统配置进行判断.吞吐量优先的并行收集器如上文所述,并行收集器主要以到达一定的吞吐量为目标,适用于科学技术和后台处理等.典型配置:java -Xmx3800m -Xms3800m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20-XX:+UseParallelGC:选择垃圾收集器为并行收集器.此配置仅对年轻代有效.即上述配置下,年轻代使用并发收集,而年老代仍旧使用串行收集.-XX:ParallelGCThreads=20:配置并行收集器的线程数,即:同时多少个线程一起进行垃圾回收.此值最好配置与处理器数目相等.java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20 -XX:+UseParallelOldGC-XX:+UseParallelOldGC:配置年老代垃圾收集方式为并行收集.JDK6.0支持对年老代并行收集.java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:MaxGCPauseMillis=100-XX:MaxGCPauseMillis=100:设置每次年轻代垃圾回收的最长时间,如果无法满足此时间,JVM会自动调整年轻代大小,以满足此值.java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:MaxGCPauseMillis=100 -XX:+UseAdaptiveSizePolicy-XX:+UseAdaptiveSizePolicy:设置此选项后,并行收集器会自动选择年轻代区大小和相应的Survivor区比例,以达到目标系统规定的最低相应时间或者收集频率等,此值建议使用并行收集器时,一直打开.响应时间优先的并发收集器如上文所述,并发收集器主要是保证系统的响应时间,减少垃圾收集时的停顿时间.适用于应用服务器,电信领域等.典型配置:java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:ParallelGCThreads=20 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC-XX:+UseConcMarkSweepGC:设置年老代为并发收集.测试中配置这个以后,-XX:NewRatio=4的配置失效了,原因不明.所以,此时年轻代大小最好用-Xmn设置. -XX:+UseParNewGC:设置年轻代为并行收集.可与CMS收集同时使用.JDK5.0以上,JVM会根据系统配置自行设置,所以无需再设置此值.java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseConcMarkSweepGC -XX:CMSFullGCsBeforeCompaction=5 -XX:+UseCMSCompactAtFullCollection-XX:CMSFullGCsBeforeCompaction:由于并发收集器不对内存空间进行压缩,整理,所以运行一段时间以后会产生"碎片",使得运行效率降低.此值设置运行多少次GC以后对内存空间进行压缩,整理.-XX:+UseCMSCompactAtFullCollection:打开对年老代的压缩.可能会影响性能,但是可以消除碎片辅助信息JVM提供了大量命令行参数,打印信息,供调试使用.主要有以下一些:-XX:+PrintGC输出形式:[GC 118250K->113543K(130112K), 0.0094143 secs][Full GC 121376K->10414K(130112K), 0.0650971 secs]-XX:+PrintGCDetails输出形式:[GC [DefNew: 8614K->781K(9088K), 0.0123035 secs] 118250K->113543K(130112K), 0.0124633 secs][GC [DefNew: 8614K->8614K(9088K), 0.0000665 secs][Tenured: 112761K->10414K(121024K), 0.0433488 secs] 121376K->10414K(130112K), 0.0436268 secs]-XX:+PrintGCTimeStamps -XX:+PrintGC:PrintGCTimeStamps可与上面两个混合使用输出形式:11.851: [GC 98328K->93620K(130112K), 0.0082960 secs]-XX:+PrintGCApplicationConcurrentTime:打印每次垃圾回收前,程序未中断的执行时间.可与上面混合使用输出形式:Application time: 0.5291524 seconds-XX:+PrintGCApplicationStoppedTime:打印垃圾回收期间程序暂停的时间.可与上面混合使用输出形式:Total time for which application threads were stopped:0.0468229 seconds-XX:PrintHeapAtGC:打印GC前后的详细堆栈信息输出形式:34.702: [GC {Heap before gc invocations=7:def new generation total 55296K, used 52568K [0x1ebd0000, 0x227d0000, 0x227d0000)eden space 49152K, 99% used [0x1ebd0000, 0x21bce430, 0x21bd0000)from space 6144K, 55% used [0x221d0000, 0x22527e10, 0x227d0000)to space 6144K, 0% used [0x21bd0000, 0x21bd0000, 0x221d0000)tenured generation total 69632K, used 2696K [0x227d0000, 0x26bd0000, 0x26bd0000)the space 69632K, 3% used [0x227d0000, 0x22a720f8, 0x22a72200,0x26bd0000)compacting perm gen total 8192K, used 2898K [0x26bd0000, 0x273d0000, 0x2abd0000)the space 8192K, 35% used [0x26bd0000, 0x26ea4ba8, 0x26ea4c00,0x273d0000)ro space 8192K, 66% used [0x2abd0000, 0x2b12bcc0, 0x2b12be00,0x2b3d0000)rw space 12288K, 46% used [0x2b3d0000, 0x2b972060, 0x2b972200,0x2bfd0000)34.735: [DefNew: 52568K->3433K(55296K), 0.0072126 secs] 55264K->6615K(124928K)Heap after gc invocations=8:def new generation total 55296K, used 3433K [0x1ebd0000, 0x227d0000, 0x227d0000)eden space 49152K, 0% used [0x1ebd0000, 0x1ebd0000, 0x21bd0000)from space 6144K, 55% used [0x21bd0000, 0x21f2a5e8, 0x221d0000)to space 6144K, 0% used [0x221d0000, 0x221d0000, 0x227d0000)tenured generation total 69632K, used 3182K [0x227d0000, 0x26bd0000, 0x26bd0000)the space 69632K, 4% used [0x227d0000, 0x22aeb958, 0x22aeba00,0x26bd0000)compacting perm gen total 8192K, used 2898K [0x26bd0000, 0x273d0000, 0x2abd0000)the space 8192K, 35% used [0x26bd0000, 0x26ea4ba8, 0x26ea4c00,0x273d0000)ro space 8192K, 66% used [0x2abd0000, 0x2b12bcc0, 0x2b12be00,0x2b3d0000)rw space 12288K, 46% used [0x2b3d0000, 0x2b972060, 0x2b972200,0x2bfd0000)}, 0.0757599 secs]-Xloggc:filename:与上面几个配合使用,把相关日志信息记录到文件以便分析.常见配置汇总堆设置-Xms:初始堆大小-Xmx:最大堆大小-XX:NewSize=n:设置年轻代大小-XX:NewRatio=n:设置年轻代和年老代的比值.如:为3,表示年轻代与年老代比值为1:3,年轻代占整个年轻代年老代和的1/4-XX:SurvivorRatio=n:年轻代中Eden区与两个Survivor区的比值.注意Survivor区有两个.如:3,表示Eden:Survivor=3:2,一个Survivor区占整个年轻代的1/5-XX:MaxPermSize=n:设置持久代大小收集器设置-XX:+UseSerialGC:设置串行收集器-XX:+UseParallelGC:设置并行收集器-XX:+UseParalledlOldGC:设置并行年老代收集器-XX:+UseConcMarkSweepGC:设置并发收集器垃圾回收统计信息-XX:+PrintGC-XX:+PrintGCDetails-XX:+PrintGCTimeStamps-Xloggc:filename并行收集器设置-XX:ParallelGCThreads=n:设置并行收集器收集时使用的CPU数.并行收集线程数.-XX:MaxGCPauseMillis=n:设置并行收集最大暂停时间-XX:GCTimeRatio=n:设置垃圾回收时间占程序运行时间的百分比.公式为1/(1+n)并发收集器设置-XX:+CMSIncrementalMode:设置为增量模式.适用于单CPU情况.-XX:ParallelGCThreads=n:设置并发收集器年轻代收集方式为并行收集时,使用的CPU数.并行收集线程数.调优总结年轻代大小选择响应时间优先的应用:尽可能设大,直到接近系统的最低响应时间限制(根据实际情况选择).在此种情况下,年轻代收集发生的频率也是最小的.同时,减少到达年老代的对象.吞吐量优先的应用:尽可能的设置大,可能到达Gbit的程度.因为对响应时间没有要求,垃圾收集可以并行进行,一般适合8CPU以上的应用.年老代大小选择响应时间优先的应用:年老代使用并发收集器,所以其大小需要小心设置,一般要考虑并发会话率和会话持续时间等一些参数.如果堆设置小了,可以会造成内存碎片,高回收频率以及应用暂停而使用传统的标记清除方式;如果堆大了,则需要较长的收集时间.最优化的方案,一般需要参考以下数据获得:并发垃圾收集信息持久代并发收集次数传统GC信息花在年轻代和年老代回收上的时间比例减少年轻代和年老代花费的时间,一般会提高应用的效率吞吐量优先的应用:一般吞吐量优先的应用都有一个很大的年轻代和一个较小的年老代.原因是,这样可以尽可能回收掉大部分短期对象,减少中期的对象,而年老代尽存放长期存活对象.较小堆引起的碎片问题因为年老代的并发收集器使用标记,清除算法,所以不会对堆进行压缩.当收集器回收时,他会把相邻的空间进行合并,这样可以分配给较大的对象.但是,当堆空间较小时,运行一段时间以后,就会出现"碎片",如果并发收集器找不到足够的空间,那么并发收集器将会停止,然后使用传统的标记,清除方式进行回收.如果出现"碎片",可能需要进行如下配置:-XX:+UseCMSCompactAtFullCollection:使用并发收集器时,开启对年老代的压缩.-XX:CMSFullGCsBeforeCompaction=0:上面配置开启的情况下,这里设置多少次Full GC后,对年老代进行压缩在同一个工程下,有两个类,这两个类中只有很少的变动,而最关健的FOR却没有一点变动,可是当我分别运行这两个程序的时候却出现一个很严重的问题,一个程序循环的快,一个循环的慢.这到底是怎么回事呢~苦苦寻找了半天也没有想到是为什么,因为程序改变的部分根不影响我循环的速度,可是结果却是有很大的差别,一个大约是在一分钟这内就可以循环完,可是另一个却需要六七分钟,这根本就不是一个数据理级的麻.两个完全一样的循环,从代码上根本上是看不出有什么问题.不得以求助同事吧,可是同事看了也感觉很诡异,两个人在那订着代码又看了一个多小时,最后同事让我来个干净点的,关机重启.我到也听话,就顺着同事的意思去了,可就在关机的这个时候他突然说是不是内存的问题,我也空然想到了,还真的有可能是内存的问题,因为快的那个在我之前运行程序之前可给过 1G的内存啊,而后来的这个我好像是没有设过内存啊,机器起来了,有了这个想法进去看看吧,结果正中要害,果真是慢的那个没有开内存,程序运行时只不过是 JVM默认开的内存.我初步分析是因为内存太小,而我的程序所用内存又正好卡在JVM所开内存边上,不至于溢出.当程序运行时就得花费大部分时间去调用 GC去,这样就导致了为什么相同的循环出现两种不同的效率~!顺便把内存使用情况的方法也贴出来:public static String getMemUsage() {long free = ng.Runtime.getRuntime().freeMemory();long total = ng.Runtime.getRuntime().totalMemory();StringBuffer buf = new StringBuffer();buf.append("[Mem: used ").append((total-free)>>20).append("M free ").append(free>>20).append("M total ").append(total>>20).append("M]");return buf.toString();}google一下,大概就说JVM是这样来操作内存:堆(Heap)和非堆(Non-heap)内存按照官方的说法:"Java 虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配.堆是在 Java 虚拟机启动时创建的.""在JVM中堆之外的内存称为非堆内存(Non-heap memory)".可以看出JVM主要管理两种类型的内存:堆和非堆.简单来说堆就是Java代码可及的内存,是留给开发人员使用的;非堆就是JVM留给自己用的,所以方法区,JVM内部处理或优化所需的内存(如JIT编译后的代码缓存),每个类结构(如运行时常数池,字段和方法数据)以及方法和构造方法的代码都在非堆内存中.堆内存分配JVM初始分配的内存由-Xms指定,默认是物理内存的1/64;JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4.默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时, JVM会减少堆直到-Xms的最小限制.因此服务器一般设置-Xms,-Xmx相等以避免在每次GC 后调整堆的大小.非堆内存分配JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4.JVM内存限制(最大值)首先JVM内存首先受限于实际的最大物理内存,假设物理内存无限大的话,JVM内存的最大值跟操作系统有很大的关系.简单的说就32位处理器虽然可控内存空间有4GB,但是具体的操作系统会给一个限制,这个限制一般是 2GB-3GB(一般来说Windows系统下为1.5G-2G,Linux系统下为2G-3G),而64bit以上的处理器就不会有限制了JVM内存的调优1. Heap设定与垃圾回收Java Heap分为3个区,Young,Old和Permanent.Young保存刚实例化的对象.当该区被填满时,GC会将对象移到Old 区.Permanent区则负责保存反射对象,本文不讨论该区.JVM的Heap分配可以使用-X参数设定,-Xms初始Heap大小-Xmxjava heap最大值-Xmnyoung generation的heap大小JVM有2个GC线程.第一个线程负责回收Heap的Young区.第二个线程在Heap 不足时,遍历Heap,将Young 区升级为Older区.Older区的大小等于-Xmx减去-Xmn,不能将-Xms的值设的过大,因为第二个线程被迫运行会降低JVM的性能.为什么一些程序频繁发生GC?有如下原因:l 程序内调用了System.gc()或Runtime.gc().l 一些中间件软件调用自己的GC方法,此时需要设置参数禁止这些GC.l Java的Heap太小,一般默认的Heap值都很小.l 频繁实例化对象,Release对象.此时尽量保存并重用对象,例如使用StringBuffer()和String().如果你发现每次GC后,Heap的剩余空间会是总空间的50%,这表示你的Heap处于健康状态.许多Server端的Java程序每次GC后最好能有65%的剩余空间.经验之谈:1.Server端JVM最好将-Xms和-Xmx设为相同值.为了优化GC,最好让-Xmn值约等于-Xmx的1/3[2].2.一个GUI程序最好是每10到20秒间运行一次GC,每次在半秒之内完成[2].注意:1.增加Heap的大小虽然会降低GC的频率,但也增加了每次GC的时间.并且GC 运行时,所有的用户线程将暂停,也就是GC期间,Java应用程序不做任何工作. 2.Heap大小并不决定进程的内存使用量.进程的内存使用量要大于-Xmx定义的值,因为Java为其他任务分配内存,例如每个线程的Stack等.2.Stack的设定每个线程都有他自己的Stack.-Xss每个线程的Stack大小Stack的大小限制着线程的数量.如果Stack过大就好导致内存溢漏.-Xss参数决定Stack大小,例如-Xss1024K.如果Stack太小,也会导致Stack溢漏.3.硬件环境硬件环境也影响GC的效率,例如机器的种类,内存,swap空间,和CPU的数量.如果你的程序需要频繁创建很多transient对象,会导致JVM频繁GC.这种情况你可以增加机器的内存,来减少Swap空间的使用[2].4.4种GC第一种为单线程GC,也是默认的GC.,该GC适用于单CPU机器.第二种为Throughput GC,是多线程的GC,适用于多CPU,使用大量线程的程序.第二种GC与第一种GC相似,不同在于GC在收集Young区是多线程的,但在Old 区和第一种一样,仍然采用单线程.-XX:+UseParallelGC参数启动该GC.第三种为Concurrent Low Pause GC,类似于第一种,适用于多CPU,并要求缩短因GC造成程序停滞的时间.这种GC可以在Old区的回收同时,运行应用程序.-XX:+UseConcMarkSweepGC参数启动该GC.第四种为Incremental Low Pause GC,适用于要求缩短因GC造成程序停滞的时间.这种GC可以在Young区回收的同时,回收一部分Old区对象.-Xincgc参数启动该GC.。
JVM调优参数、方法、工具以及案例总结
JVM 调优参数、⽅法、⼯具以及案例总结这种⽂章挺难写的,⼀是JVM参数巨多,⼆是内容枯燥乏味,但是想理解JVM调优⼜是没法避开的环节,本⽂主要⽤来总结梳理便于以后翻阅,主要围绕四个⼤的⽅⾯展开,分别是JVM调优参数、JVM调优⽅法(流程)、JVM调优⼯具、JVM 调优案例,调优案例⽬前正在分析,会在将来补上。
垃圾回收有关参数参数部分,这⼉只是做⼀个总结,更详细更新的内容请参考Oracle官⽹:处理器组合参数关于JVM垃圾处理器区别,参考:-XX:+UseSerialGC = Serial New (DefNew) + Serial Old适⽤于⼩型程序。
默认情况下不会是这种选项,HotSpot 会根据计算及配置和JDK 版本⾃动选择收集器-XX:+UseParNewGC = ParNew + SerialOld这个组合已经很少⽤(在某些版本中已经废弃),详情参考:-XX:+UseConc(urrent)MarkSweepGC = ParNew + CMS + Serial Old-XX:+UseParallelGC = Parallel Scavenge + Parallel Old (1.8默认) 【PS + SerialOld】-XX:+UseParallelOldGC = Parallel Scavenge + Parallel Old -XX:+UseG1GC = G1Linux中没找到默认GC的查看⽅法,⽽windows中会打印UseParallelGCjava +XX:+PrintCommandLineFlags -version 通过GC 的⽇志来分辨Linux下1.8版本默认的垃圾回收器到底是什么?1.8.0_181 默认(看不出来)Copy MarkCompact 1.8.0_222 默认 PS + PO虚拟机参数并⾏收集器相关参数参数名称含义默认值解释说明-Xms 初始堆⼤⼩物理内存的1/64(<1GB)默认(MinHeapFreeRatio 参数可以调整)空余堆内存⼩于40%时,JVM 就会增⼤堆直到-Xmx 的最⼤限制.-Xmx 最⼤堆⼤⼩物理内存的1/4(<1GB)默认(MaxHeapFreeRatio 参数可以调整)空余堆内存⼤于70%时,JVM 会减少堆直到 -Xms 的最⼩限制-Xmn 年轻代⼤⼩(1.4or lator)注意:此处的⼤⼩是(eden+ 2 survivor space).与jmap -heap 中显⽰的New gen 是不同的。
JVM调优参数详解
JVM调优参数详解GC有两种类型:Scavenge GC 和Full GC1、Scavenge GC⼀般情况下,当新对象⽣成,并且在Eden申请空间失败时,就会触发Scavenge GC,堆的Eden区域进⾏GC,清除⾮存活对象,并且把尚且存活的对象移动到Survivor的两个区中。
2、Full GC对整个堆进⾏整理,包括Young、Tenured和Perm。
Full GC ⽐Scavenge GC要慢,因此应该尽可能减少Full GC,有如下原因可能导致Full GCa、Tenured被写满;b、Perm域被写满c、System.gc()被显⽰调⽤d、上⼀次GC之后Heap的各域分配策略动态变化;-Xmx512m -Xms512m -Xmn192m -Xss128kJVM中最⼤堆⼤⼩受三⽅⾯限制,相关操作系统的数据模型(32位还是64位)限制;系统的可⽤虚拟内存限制;系统的可⽤物理内存限制-Xmx512m:设置JVM实例堆最⼤可⽤内存为512M。
-Xms512m:设置JVM促使内存为512m。
此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。
-Xmn192m设置年轻代⼤⼩为192m。
整个JVM内存⼤⼩=年轻代⼤⼩ + 年⽼代⼤⼩ + 持久代⼤⼩。
持久代⼀般固定⼤⼩为64m,所以增⼤年轻代后,将会减⼩年⽼代⼤⼩。
此值对系统性能影响较⼤,Sun官⽅推荐配置为整个堆的3/8。
-Xss128k设置每个线程的堆栈⼤⼩。
JDK5.0以后每个线程堆栈⼤⼩为1M,以前每个线程堆栈⼤⼩为256K。
更具应⽤的线程所需内存⼤⼩进⾏调整。
在相同物理内存下,减⼩这个值能⽣成更多的线程。
但是操作系统对⼀个进程内的线程数还是有限制的,不能⽆限⽣成,经验值在3000~5000左右。
注意下⾯问题:(1)增加Heap的⼤⼩虽然会降低GC的频率,但也增加了每次GC的时间。
并且GC运⾏时,所有的⽤户线程将暂停,也就是GC期间,Java应⽤程序不做任何⼯作。
java jvm调优面试题
java jvm调优面试题在Java开发中,JVM(Java虚拟机)的性能调优是一个非常重要的方面。
优化JVM的性能可以提高应用程序的运行效率和响应速度。
为了帮助读者准备面试,本文将介绍一些与Java JVM调优相关的面试题。
以下是几个常见的问题:问题一:什么是JVM调优?JVM调优是指对Java虚拟机进行优化,以提高Java应用程序的性能和吞吐量。
通过对JVM参数的调整、内存管理以及垃圾收集等方面的优化,可以使Java应用程序更加高效地运行。
问题二:如何调整JVM的参数?可以通过在启动Java应用程序时,使用"-X"参数进行调整。
例如,可以使用"-Xms"参数调整初始堆大小,使用"-Xmx"参数调整最大堆大小。
同时,还可以使用"-XX"参数进行更加细致的调优。
问题三:有哪些常见的JVM参数?常见的JVM参数包括:- "-Xms":设置初始堆大小- "-Xmx":设置最大堆大小- "-XX:NewRatio":设置年轻代与老年代的比例- "-XX:MaxPermSize":设置永久代的最大大小(JDK8之前)- "-XX:MaxMetaspaceSize":设置元数据区的最大大小(JDK8之后)问题四:什么是垃圾收集器(GC)?垃圾收集器是JVM中负责回收无用对象的组件。
垃圾收集器通过标记、清除和压缩等过程来释放不再使用的内存,并将其回收供其他对象使用。
问题五:有哪些常见的垃圾收集器?常见的垃圾收集器包括:- Serial收集器:单线程的、使用复制算法的收集器,适用于小型应用程序或者客户端应用程序。
- Parallel收集器:多线程的、使用复制算法的收集器,适用于需要追求较高吞吐量的应用程序。
- CMS收集器:并发标记清除算法的收集器,适用于需要较短停顿时间的应用程序。
gc常用调优参数
gc常用调优参数GC(Garbage Collection)是Java虚拟机(JVM)的一项重要功能,用于自动管理内存。
为了优化GC的性能,我们可以通过调整一些常用的参数来达到更好的效果。
本文将介绍一些常用的GC调优参数及其作用,帮助读者在实际应用中进行性能优化。
1. -Xmx和-Xms:这两个参数用来设置JVM的堆内存大小。
-Xmx 用于设置最大堆内存大小,-Xms用于设置初始堆内存大小。
合理设置这两个参数可以避免频繁的堆内存扩容和收缩,提高应用的性能。
2. -XX:NewRatio:这个参数用于设置新生代和老年代的比例。
默认情况下,新生代占整个堆内存的1/3,老年代占2/3。
根据应用的特点,可以适当调整这个比例以提高GC的效率。
3. -XX:SurvivorRatio:这个参数用于设置Eden区和Survivor区的比例。
默认情况下,Eden区占新生代的8/10,Survivor区占新生代的1/10。
根据应用的特点,可以适当调整这个比例以减少对象在Eden区的存活时间,从而减少GC的次数。
4. -XX:MaxTenuringThreshold:这个参数用于设置对象进入老年代的年龄阈值。
默认情况下,对象经过15次Minor GC仍然存活,就会被移到老年代。
根据应用的特点,可以适当调整这个阈值以减少对象进入老年代的次数,减轻老年代的GC压力。
5. -XX:+UseConcMarkSweepGC:这个参数用于启用CMS (Concurrent Mark and Sweep)垃圾收集器。
CMS收集器是一种并发收集器,可以在主线程运行的同时进行垃圾收集,减少应用的停顿时间。
适用于对响应时间要求较高的应用场景。
6. -XX:+UseG1GC:这个参数用于启用G1(Garbage-First)垃圾收集器。
G1收集器是一种面向服务端应用的垃圾收集器,可以更好地控制垃圾收集的停顿时间。
适用于内存较大的应用场景。
jvm性能调优面试题
jvm性能调优面试题在进行JVM性能调优时,面试官可能会提出一些相关问题,以测试你的知识和经验。
本文将回答一系列常见的JVM性能调优面试题。
以下是这些问题的解答:题目一:请解释什么是JVM性能调优?JVM性能调优是通过调整Java虚拟机(JVM)的配置参数和优化Java应用程序代码,以提高应用程序的性能。
这涉及到优化内存使用、垃圾收集、线程管理、类加载等方面。
题目二:列举几个常用的JVM调优工具。
常见的JVM调优工具包括但不限于以下几个:1. VisualVM:可视化的JVM监控和性能分析工具,提供了图形化界面以展示各种性能指标和线程信息。
2. jstat:可监控和调优JVM的命令行工具,用于查看各种垃圾收集相关的统计信息。
3. jmap:用于生成Java堆和永久代的转储文件,便于内存分析和内存泄漏检测。
4. jstack:用于生成Java线程的转储文件,便于分析线程问题和死锁情况。
题目三:你遇到过哪些JVM性能瓶颈问题?你是如何解决的?面试官可能希望了解你在JVM性能调优方面的实际经验。
你可以分享一到两个你遇到过的问题,并解释你是如何解决这些问题的。
例如:我曾经遇到过一个Java应用程序的内存泄漏问题。
通过使用jmap生成内存转储文件,我发现堆中有大量的对象无法被垃圾收集器回收。
我使用内存分析工具进行了分析,并发现这些对象是由于不正确的缓存机制导致的。
我进行了代码修复,正确地释放了这些对象,从而解决了内存泄漏问题。
题目四:如何设置JVM的堆大小?你可以解释你对JVM堆大小设置的了解。
例如,你可以提到-Xms参数用于设置堆的初始大小,-Xmx参数用于设置堆的最大大小。
还可以提及如何根据应用程序的需求和硬件配置来决定合适的堆大小。
题目五:什么是JIT编译器?它对JVM性能有何影响?JIT(Just-In-Time)编译器是JVM的一部分,用于将Java字节码动态编译成机器码,以提高代码的执行效率。
jvm参数配置原则
jvm参数配置原则JVM参数配置原则JVM(Java Virtual Machine)是Java程序运行的平台,通过JVM 参数的配置可以对Java应用的性能和行为进行调优。
合理的JVM参数配置能够提升应用的性能和稳定性,因此掌握JVM参数配置原则是非常重要的。
本文将介绍一些常用的JVM参数配置原则,帮助开发人员更好地进行JVM参数的调优。
一、根据应用需求进行内存分配在JVM参数配置中,最重要的参数是-Xmx和-Xms,它们用于指定JVM堆内存的最大值和初始值。
合理配置堆内存大小可以避免内存溢出或浪费。
通常情况下,可以将-Xmx设置为物理内存的70%到80%,而-Xms则可以设置为-Xmx的一半。
这样可以保证应用有足够的内存供应,并且避免堆内存的频繁扩容和回收。
二、设置合适的新生代和老年代比例JVM的堆内存主要分为新生代和老年代两部分。
新生代用于存放新创建的对象,而老年代用于存放生命周期较长的对象。
通过参数-XX:NewRatio可以设置新生代和老年代的比例。
一般情况下,可以将新生代的比例设置为3或4,即新生代占整个堆内存的1/3或1/4。
这样可以保证新生代有足够的空间进行对象的创建和回收。
三、调整垃圾回收算法JVM的垃圾回收算法有很多种,如Serial、Parallel、CMS和G1等。
不同的应用场景可以选择不同的垃圾回收算法以达到最优的性能。
对于较小的应用,可以选择Serial或Parallel垃圾回收算法,它们在单线程和多线程环境下都有良好的性能表现。
对于大型应用,可以选择CMS或G1垃圾回收算法,它们能够在较短时间内完成垃圾回收,减少应用的停顿时间。
四、设置合适的垃圾回收参数除了选择合适的垃圾回收算法外,还需要根据具体应用的特点设置合适的垃圾回收参数。
例如,可以通过参数-XX:MaxGCPauseMillis设置最大垃圾回收停顿时间,以控制垃圾回收对应用的影响。
可以通过参数-XX:ParallelGCThreads设置并行垃圾回收的线程数,以提高垃圾回收的效率。
JVM内存设置多大合适?Xmx和Xmn如何设置?
JVM内存设置多⼤合适?Xmx和Xmn如何设置?JVM内存设置多⼤合适?Xmx和Xmn如何设置?问题:新上线⼀个java服务,或者是RPC或者是WEB站点,内存的设置该怎么设置呢?设置成多⼤⽐较合适,既不浪费内存,⼜不影响性能呢?分析:依据的原则是根据Java Performance⾥⾯的推荐公式来进⾏设置。
296d1509689688.png具体来讲:Java整个堆⼤⼩设置,Xmx 和 Xms设置为⽼年代存活对象的3-4倍,即FullGC之后的⽼年代内存占⽤的3-4倍永久代 PermSize和MaxPermSize设置为⽼年代存活对象的1.2-1.5倍。
年轻代Xmn的设置为⽼年代存活对象的1-1.5倍。
⽼年代的内存⼤⼩设置为⽼年代存活对象的2-3倍。
BTW:1、Sun官⽅建议年轻代的⼤⼩为整个堆的3/8左右,所以按照上述设置的⽅式,基本符合Sun的建议。
2、堆⼤⼩=年轻代⼤⼩+年⽼代⼤⼩,即xmx=xmn+⽼年代⼤⼩。
Permsize不影响堆⼤⼩。
3、为什么要按照上⾯的来进⾏设置呢?没有具体的说明,但应该是根据多种调优之后得出的⼀个结论。
如何确认⽼年代存活对象⼤⼩?⽅式1(推荐/⽐较稳妥):JVM参数中添加GC⽇志,GC⽇志中会记录每次FullGC之后各代的内存⼤⼩,观察⽼年代GC之后的空间⼤⼩。
可观察⼀段时间内(⽐如2天)的FullGC之后的内存情况,根据多次的FullGC之后的⽼年代的空间⼤⼩数据来预估FullGC之后⽼年代的存活对象⼤⼩(可根据多次FullGC之后的内存⼤⼩取平均值)⽅式2:(强制触发FullGC, 会影响线上服务,慎⽤)⽅式1的⽅式⽐较可⾏,但需要更改JVM参数,并分析⽇志。
同时,在使⽤CMS回收器的时候,有可能不能触发FullGC(只发⽣CMS GC),所以⽇志中并没有记录FullGC的⽇志。
在分析的时候就⽐较难处理。
BTW:使⽤jstat -gcutil⼯具来看FullGC的时候, CMS GC是会造成2次的FullGC次数增加。
javajvm参数-Xms-Xmx-Xmn-Xss调优总结
java jvm 参数 -Xms -Xmx -Xmn -Xss 调优总结常见配置举例堆大小设置JVM 中最大堆大小有三方面限制:相关操作系统的数据模型(32-bt还是64-bit)限制;系统的可用虚拟内存限制;系统的可用物理内存限制.32位系统下,一般限制在1.5G~2G;64为操作系统对内存无限制.我在Windo ws Server2003 系统,3.5G物理内存,JDK5.0下测试,最大可设置为1478m.典型设置:java -Xmx3550m -Xms3550m -Xmn2g -Xss128k-Xmx3550m:设置JVM最大可用内存为3550M.-Xms3550m:设置JVM促使内存为3550m.此值可以设置与-Xmx相同,以避免每次垃圾回收完成后J VM重新分配内存.-Xmn2g:设置年轻代大小为2G.整个堆大小=年轻代大小 + 年老代大小 + 持久代大小.持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小.此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8.-Xss128k: 设置每个线程的堆栈大小.JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K.更具应用的线程所需内存大小进行调整.在相同物理内存下,减小这个值能生成更多的线程.但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右.java -Xmx3550m -Xms3550m -Xss128k -XX:NewRati o=4 -XX:Survivo rRatio=4 -XX:MaxPerm Size=16m -XX:MaxTenu ringTh reshol d=0-XX:NewRati o=4:设置年轻代(包括Eden和两个Surv ivor区)与年老代的比值(除去持久代).设置为4,则年轻代与年老代所占比值为1:4,年轻代占整个堆栈的1/5-XX:Survivo rRatio=4:设置年轻代中E den区与S urvivo r区的大小比值.设置为4,则两个Surv ivor区与一个Eden区的比值为2:4,一个Survi vor区占整个年轻代的1/6-XX:MaxPerm Size=16m:设置持久代大小为16m.-XX:MaxTenu ringTh reshol d=0: 设置垃圾最大年龄.如果设置为0的话,则年轻代对象不经过Surv ivor区,直接进入年老代. 对于年老代比较多的应用,可以提高效率.如果将此值设置为一个较大值,则年轻代对象会在Survi vor区进行多次复制,这样可以增加对象再年轻代的存活时间,增加在年轻代即被回收的概论. 回收器选择JVM给了三种选择:串行收集器,并行收集器,并发收集器,但是串行收集器只适用于小数据量的情况,所以这里的选择主要针对并行收集器和并发收集器.默认情况下,JDK5.0以前都是使用串行收集器,如果想使用其他收集器需要在启动时加入相应参数.JDK5.0以后,JVM会根据当前系统配置进行判断.吞吐量优先的并行收集器如上文所述,并行收集器主要以到达一定的吞吐量为目标,适用于科学技术和后台处理等.典型配置:java -Xmx3800m -Xms3800m -Xmn2g -Xss128k -XX:+UsePara llelGC-XX:Paralle lGCThr eads=20-XX:+UsePara llelGC:选择垃圾收集器为并行收集器.此配置仅对年轻代有效.即上述配置下,年轻代使用并发收集,而年老代仍旧使用串行收集.-XX:Paralle lGCThr eads=20:配置并行收集器的线程数,即:同时多少个线程一起进行垃圾回收.此值最好配置与处理器数目相等.java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UsePara llelGC-XX:Paralle lGCThr eads=20 -XX:+UsePara llelOl dGC-XX:+UsePara llelOl dGC:配置年老代垃圾收集方式为并行收集.JDK6.0支持对年老代并行收集.java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UsePara llelGC-XX:MaxGCPa useMil lis=100-XX:MaxGCPa useMil lis=100:设置每次年轻代垃圾回收的最长时间,如果无法满足此时间,JVM会自动调整年轻代大小,以满足此值.java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UsePara llelGC-XX:MaxGCPa useMil lis=100 -XX:+UseAdap tiveSi zePoli cy-XX:+UseAdap tiveSi zePoli cy:设置此选项后,并行收集器会自动选择年轻代区大小和相应的Survi vor区比例,以达到目标系统规定的最低相应时间或者收集频率等,此值建议使用并行收集器时,一直打开.响应时间优先的并发收集器如上文所述,并发收集器主要是保证系统的响应时间,减少垃圾收集时的停顿时间.适用于应用服务器,电信领域等.典型配置:java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:Paralle lGCThr eads=20-XX:+UseConc MarkSw eepGC-XX:+UseParN ewGC-XX:+UseConc MarkSw eepGC:设置年老代为并发收集.测试中配置这个以后,-XX:NewRati o=4的配置失效了,原因不明.所以,此时年轻代大小最好用-Xmn 设置.-XX:+UseParN ewGC:设置年轻代为并行收集.可与CMS收集同时使用.JDK5.0以上,JVM会根据系统配置自行设置,所以无需再设置此值.java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseConc MarkSw eepGC-XX:CMSFull GCsBef oreCom pactio n=5 -XX:+UseCMSC ompact AtFull Collec tion -XX:CMSFull GCsBef oreCom pactio n:由于并发收集器不对内存空间进行压缩,整理,所以运行一段时间以后会产生"碎片",使得运行效率降低.此值设置运行多少次GC以后对内存空间进行压缩,整理.-XX:+UseCMSC ompact AtFull Collec tion:打开对年老代的压缩.可能会影响性能,但是可以消除碎片辅助信息JVM提供了大量命令行参数,打印信息,供调试使用.主要有以下一些:-XX:+PrintGC输出形式:[GC 118250K->113543K(130112K), 0.0094143 secs][Full GC 121376K->10414K(130112K), 0.0650971 secs]-XX:+PrintGC Detail s输出形式:[GC [DefNew: 8614K->781K(9088K), 0.0123035 secs]118250K->113543K(130112K), 0.0124633 secs][GC [DefNew: 8614K->8614K(9088K), 0.0000665 secs][Tenured:112761K->10414K(121024K), 0.0433488 secs] 121376K->10414K(130112K), 0.0436268 secs]-XX:+PrintGC TimeSt amps -XX:+PrintGC:PrintGC TimeSt amps可与上面两个混合使用输出形式:11.851: [GC 98328K->93620K(130112K), 0.0082960 secs]-XX:+PrintGC Applic ationC oncurr entTim e:打印每次垃圾回收前,程序未中断的执行时间.可与上面混合使用输出形式:Applica tion time: 0.5291524 seconds-XX:+PrintGC Applic ationS topped Time:打印垃圾回收期间程序暂停的时间.可与上面混合使用输出形式:Total time for which applica tion threads were stopped: 0.0468229 seconds-XX:PrintHe apAtGC:打印GC前后的详细堆栈信息输出形式:34.702: [GC {Heap beforegc invocat ions=7:def new generat ion total 55296K, used 52568K[0x1ebd0000, 0x227d0000, 0x227d0000)eden space 49152K, 99% used [0x1ebd0000, 0x21bce430, 0x21bd0000)from space 6144K, 55% used [0x221d0000, 0x22527e10, 0x227d0000)to space 6144K, 0% used [0x21bd0000, 0x21bd0000, 0x221d0000)tenured generat ion total 69632K, used 2696K [0x227d0000, 0x26bd0000,0x26bd0000)the space 69632K,3% used [0x227d0000, 0x22a720f8, 0x22a72200, 0x26bd0000) compact ing perm gen total 8192K, used 2898K [0x26bd0000, 0x273d0000,0x2abd0000)the space 8192K, 35% used [0x26bd0000, 0x26ea4ba8, 0x26ea4c00, 0x273d0000) ro space 8192K, 66% used [0x2abd0000, 0x2b12b cc0, 0x2b12b e00, 0x2b3d0000) rw space 12288K,46% used [0x2b3d0000, 0x2b972060, 0x2b972200, 0x2bfd0000) 34.735: [DefNew: 52568K->3433K(55296K), 0.0072126 secs]55264K->6615K(124928K)Heap after gc invocat ions=8:def new generat ion total 55296K, used 3433K [0x1ebd0000, 0x227d0000,0x227d0000)eden space 49152K, 0% used [0x1ebd0000, 0x1ebd0000, 0x21bd0000)from space 6144K, 55% used [0x21bd0000, 0x21f2a5e8, 0x221d0000)to space 6144K, 0% used [0x221d0000, 0x221d0000, 0x227d0000)tenured generat ion total 69632K, used 3182K [0x227d0000, 0x26bd0000,0x26bd0000)the space 69632K,4% used [0x227d0000, 0x22aeb958, 0x22aeb a00, 0x26bd0000) compact ing perm gen total 8192K, used 2898K [0x26bd0000, 0x273d0000,0x2abd0000)the space 8192K, 35% used [0x26bd0000, 0x26ea4ba8, 0x26ea4c00, 0x273d0000) ro space 8192K, 66% used [0x2abd0000, 0x2b12b cc0, 0x2b12b e00, 0x2b3d0000) rw space 12288K,46% used [0x2b3d0000, 0x2b972060, 0x2b972200, 0x2bfd0000) }, 0.0757599 secs]-Xloggc:filenam e:与上面几个配合使用,把相关日志信息记录到文件以便分析. 常见配置汇总堆设置-Xms:初始堆大小-Xmx:最大堆大小-XX:NewSize=n:设置年轻代大小-XX:NewRati o=n:设置年轻代和年老代的比值.如:为3,表示年轻代与年老代比值为1:3,年轻代占整个年轻代年老代和的1/4-XX:Survivo rRatio=n:年轻代中Ede n区与两个S urvivo r区的比值.注意Survi vor区有两个.如:3,表示Eden:Survivo r=3:2,一个Survi vor区占整个年轻代的1/5-XX:MaxPerm Size=n:设置持久代大小收集器设置-XX:+UseSeri alGC:设置串行收集器-XX:+UsePara llelGC:设置并行收集器-XX:+UsePara lledlO ldGC:设置并行年老代收集器-XX:+UseConc MarkSw eepGC:设置并发收集器垃圾回收统计信息-XX:+PrintGC-XX:+PrintGC Detail s-XX:+PrintGC TimeSt amps-Xloggc:filenam e并行收集器设置-XX:Paralle lGCThr eads=n:设置并行收集器收集时使用的CPU数.并行收集线程数.-XX:MaxGCPa useMil lis=n:设置并行收集最大暂停时间-XX:GCTimeR atio=n:设置垃圾回收时间占程序运行时间的百分比.公式为1/(1+n)并发收集器设置-XX:+CMSIncr ementa lMode:设置为增量模式.适用于单CPU情况.-XX:Paralle lGCThr eads=n:设置并发收集器年轻代收集方式为并行收集时,使用的CPU数.并行收集线程数.调优总结年轻代大小选择响应时间优先的应用:尽可能设大,直到接近系统的最低响应时间限制(根据实际情况选择).在此种情况下,年轻代收集发生的频率也是最小的.同时,减少到达年老代的对象.吞吐量优先的应用:尽可能的设置大,可能到达Gbi t的程度.因为对响应时间没有要求,垃圾收集可以并行进行,一般适合8CP U以上的应用.年老代大小选择响应时间优先的应用:年老代使用并发收集器,所以其大小需要小心设置,一般要考虑并发会话率和会话持续时间等一些参数.如果堆设置小了,可以会造成内存碎片,高回收频率以及应用暂停而使用传统的标记清除方式;如果堆大了,则需要较长的收集时间.最优化的方案,一般需要参考以下数据获得:并发垃圾收集信息持久代并发收集次数传统GC信息花在年轻代和年老代回收上的时间比例减少年轻代和年老代花费的时间,一般会提高应用的效率吞吐量优先的应用:一般吞吐量优先的应用都有一个很大的年轻代和一个较小的年老代.原因是,这样可以尽可能回收掉大部分短期对象,减少中期的对象,而年老代尽存放长期存活对象.较小堆引起的碎片问题因为年老代的并发收集器使用标记,清除算法,所以不会对堆进行压缩.当收集器回收时,他会把相邻的空间进行合并,这样可以分配给较大的对象.但是,当堆空间较小时,运行一段时间以后,就会出现"碎片",如果并发收集器找不到足够的空间,那么并发收集器将会停止,然后使用传统的标记,清除方式进行回收.如果出现"碎片",可能需要进行如下配置:-XX:+UseCMSC ompact AtFull Collec tion:使用并发收集器时,开启对年老代的压缩.-XX:CMSFull GCsBef oreCom pactio n=0:上面配置开启的情况下,这里设置多少次Full GC后,对年老代进行压缩在同一个工程下,有两个类,这两个类中只有很少的变动,而最关健的FO R却没有一点变动,可是当我分别运行这两个程序的时候却出现一个很严重的问题,一个程序循环的快,一个循环的慢.这到底是怎么回事呢~苦苦寻找了半天也没有想到是为什么,因为程序改变的部分根不影响我循环的速度,可是结果却是有很大的差别,一个大约是在一分钟这内就可以循环完,可是另一个却需要六七分钟,这根本就不是一个数据理级的麻.两个完全一样的循环,从代码上根本上是看不出有什么问题.不得以求助同事吧,可是同事看了也感觉很诡异,两个人在那订着代码又看了一个多小时,最后同事让我来个干净点的,关机重启.我到也听话,就顺着同事的意思去了,可就在关机的这个时候他突然说是不是内存的问题,我也空然想到了,还真的有可能是内存的问题,因为快的那个在我之前运行程序之前可给过 1G的内存啊,而后来的这个我好像是没有设过内存啊,机器起来了,有了这个想法进去看看吧,结果正中要害,果真是慢的那个没有开内存,程序运行时只不过是 JVM默认开的内存.我初步分析是因为内存太小,而我的程序所用内存又正好卡在JVM所开内存边上,不至于溢出.当程序运行时就得花费大部分时间去调用GC去,这样就导致了为什么相同的循环出现两种不同的效率~!顺便把内存使用情况的方法也贴出来:publicstaticStringgetMemU sage() {long free = ng.Runtime.getRunt ime().freeMem ory();long total = ng.Runtime.getRunt ime().totalMe mory();StringB ufferbuf = new StringB uffer();buf.append("[Mem: used ").append((total-free)>>20).append("M free ").append(free>>20).append("M total ").append(total>>20).append("M]");returnbuf.toStrin g();}google一下,大概就说JVM是这样来操作内存:堆(Heap)和非堆(Non-heap)内存按照官方的说法:"Java 虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配.堆是在 Java 虚拟机启动时创建的.""在JVM中堆之外的内存称为非堆内存(Non-heap memory)".可以看出JVM主要管理两种类型的内存:堆和非堆.简单来说堆就是Java代码可及的内存,是留给开发人员使用的;非堆就是JVM留给自己用的,所以方法区,JVM内部处理或优化所需的内存(如JIT编译后的代码缓存),每个类结构(如运行时常数池,字段和方法数据)以及方法和构造方法的代码都在非堆内存中.堆内存分配JVM初始分配的内存由-Xms指定,默认是物理内存的1/64;JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4.默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时, JVM会减少堆直到-Xms的最小限制.因此服务器一般设置-Xms,-Xmx相等以避免在每次GC后调整堆的大小.非堆内存分配JVM使用-XX:PermSiz e设置非堆内存初始值,默认是物理内存的1/64;由XX:MaxPerm Size设置最大非堆内存的大小,默认是物理内存的1/4.JVM内存限制(最大值)首先JVM内存首先受限于实际的最大物理内存,假设物理内存无限大的话,JVM 内存的最大值跟操作系统有很大的关系.简单的说就32位处理器虽然可控内存空间有4GB,但是具体的操作系统会给一个限制,这个限制一般是 2GB-3GB(一般来说Win dows系统下为1.5G-2G,Linux系统下为2G-3G),而64bit以上的处理器就不会有限制了JVM内存的调优1. Heap设定与垃圾回收Ja va Heap分为3个区,Young,Old和Per manent.Young 保存刚实例化的对象.当该区被填满时,GC会将对象移到Old 区.Permane nt区则负责保存反射对象,本文不讨论该区.JVM的Hea p分配可以使用-X参数设定,-Xms初始Heap大小-Xmxjava heap最大值-Xmnyoung generat ion的he ap大小JVM有2个G C线程.第一个线程负责回收Heap的Young区.第二个线程在H eap不足时,遍历Heap,将Young区升级为Old er区.Older区的大小等于-Xmx减去-Xmn,不能将-Xms的值设的过大,因为第二个线程被迫运行会降低JVM的性能.为什么一些程序频繁发生GC?有如下原因:l 程序内调用了S ystem.gc()或Runtim e.gc().l 一些中间件软件调用自己的G C方法,此时需要设置参数禁止这些G C.l Java的He ap太小,一般默认的He ap值都很小.l 频繁实例化对象,Release对象.此时尽量保存并重用对象,例如使用Str ingBuf fer()和String().如果你发现每次GC后,Heap的剩余空间会是总空间的50%,这表示你的He ap处于健康状态.许多Serve r端的Jav a程序每次G C后最好能有65%的剩余空间.经验之谈:1.Server端JVM最好将-Xms和-Xmx设为相同值.为了优化GC,最好让-Xmn值约等于-Xmx的1/3[2].2.一个GUI程序最好是每10到20秒间运行一次GC,每次在半秒之内完成[2]. 注意:1.增加Heap的大小虽然会降低GC的频率,但也增加了每次GC的时间.并且GC运行时,所有的用户线程将暂停,也就是GC期间,Java应用程序不做任何工作. 2.Heap大小并不决定进程的内存使用量.进程的内存使用量要大于-Xmx定义的值,因为Java为其他任务分配内存,例如每个线程的Stack等.2.Stack的设定每个线程都有他自己的Sta ck.-Xss每个线程的St ack大小Stack的大小限制着线程的数量.如果Stack过大就好导致内存溢漏.-Xss参数决定Stack大小,例如-Xss1024K.如果Stack太小,也会导致Sta ck溢漏.3.硬件环境硬件环境也影响GC的效率,例如机器的种类,内存,swap空间,和CPU的数量.如果你的程序需要频繁创建很多trans ient对象,会导致JVM频繁GC.这种情况你可以增加机器的内存,来减少Swap空间的使用[2].4.4种GC第一种为单线程GC,也是默认的GC.,该GC适用于单CPU机器.第二种为Thr oughpu t GC,是多线程的GC,适用于多CPU,使用大量线程的程序.第二种GC与第一种GC相似,不同在于GC在收集Youn g区是多线程的,但在Old区和第一种一样,仍然采用单线程.-XX:+UsePara llelGC参数启动该G C.第三种为Con curren t Low Pause GC,类似于第一种,适用于多CPU,并要求缩短因G C造成程序停滞的时间.这种GC可以在Old区的回收同时,运行应用程序.-XX:+UseConc MarkSw eepGC参数启动该GC.第四种为Inc rement al Low Pause GC,适用于要求缩短因GC造成程序停滞的时间.这种GC可以在Young区回收的同时,回收一部分Ol d区对象.-Xincgc参数启动该GC.。
JVM调优之-Xms-Xmx-Xmn-Xss
JVM调优之-Xms-Xmx-Xmn-Xss1.JVM内存模型及垃圾收集算法 1.根据Java虚拟机规范,JVM将内存划分为:New(年轻代)Tenured(年⽼代)永久代(Perm) 其中New和Tenured属于堆内存,堆内存会从JVM启动参数(-Xmx:3G)指定的内存中分配,Perm不属于堆内存,有虚拟机直接分配,但可以通过-XX:PermSize -XX:MaxPermSize等参数调整其⼤⼩。
年轻代(New):年轻代⽤来存放JVM刚分配的Java对象年⽼代(Tenured):年轻代中经过垃圾回收没有回收掉的对象将被Copy到年⽼代永久代(Perm):永久代存放Class、Method元信息,其⼤⼩跟项⽬的规模、类、⽅法的量有关,⼀般设置为128M就⾜够,设置原则是预留30%的空间。
New⼜分为⼏个部分:Eden:Eden⽤来存放JVM刚分配的对象Survivor1Survivro2:两个Survivor空间⼀样⼤,当Eden中的对象经过垃圾回收没有被回收掉时,会在两个Survivor之间来回Copy,当满⾜某个条件,⽐如Copy次数,就会被Copy 到Tenured。
显然,Survivor只是增加了对象在年轻代中的逗留时间,增加了被垃圾回收的可能性。
2.垃圾回收算法 垃圾回收算法可以分为三类,都基于标记-清除(复制)算法:Serial算法(单线程)并⾏算法并发算法 JVM会根据机器的硬件配置对每个内存代选择适合的回收算法,⽐如,如果机器多于1个核,会对年轻代选择并⾏算法,关于选择细节请参考JVM调优⽂档。
稍微解释下的是,并⾏算法是⽤多线程进⾏垃圾回收,回收期间会暂停程序的执⾏,⽽并发算法,也是多线程回收,但期间不停⽌应⽤执⾏。
所以,并发算法适⽤于交互性⾼的⼀些程序。
经过观察,并发算法会减少年轻代的⼤⼩,其实就是使⽤了⼀个⼤的年⽼代,这反过来跟并⾏算法相⽐吞吐量相对较低。
还有⼀个问题是,垃圾回收动作何时执⾏?当年轻代内存满时,会引发⼀次普通GC,该GC仅回收年轻代。
常用的jvm调优参数
常用的jvm调优参数JVM是Java虚拟机的缩写,是Java语言的基础。
JVM 提供了许多不同的调优参数,可用于优化Java虚拟机的性能和资源管理。
这些参数可以通过修改JVM的启动参数来配置。
本文将介绍一些常用的jvm调优参数。
1. -Xmx和-Xms这两个参数分别控制Java虚拟机的最大和最小内存使用量。
-Xmx参数指定JVM最多能够使用的堆内存大小,而-Xms参数指定JVM在启动时要使用的最小堆内存大小。
根据应用程序的需要,可以根据需要设置这些参数的值以提高Java虚拟机的性能。
2. -XX:PermSize和-XX:MaxPermSize这些参数指定了Java虚拟机的永久代大小。
永久代是Java虚拟机中的一部分内存,用于存储应用程序类信息、方法、变量名等元数据信息。
通过修改这些参数的值,可以显着减少Java虚拟机的内存使用。
3. -XX:+UseConcMarkSweepGC和-XX:+UseG1GC这些参数指定了Java虚拟机使用的GC算法。
ConcMarkSweepGC是一种并发垃圾收集算法,G1GC则是一种较为新的并发GC算法。
使用-ConcMarkSweepGC参数时,垃圾收集器将并发执行,并在应用程序继续运行的同时回收内存。
使用-UseG1GC参数时,GC算法将把所有内存分为若干小块,每次只回收其中的一部分,以减少垃圾回收的延迟时间。
4. -XX:MaxTenuringThreshold和-XX:SurvivorRatio这些参数控制Java虚拟机在执行垃圾回收时的行为。
MaxTenuringThreshold参数指定对象在“老年代”中存活的时间阈值,而SurvivorRatio参数指定Eden空间与Survivor空间的大小比例。
通过对这些参数的调整,可以优化垃圾回收器的性能。
5. -XX:+UseParallelGC和-XX:+UseParallelOldGC这些参数可用于控制Java虚拟机使用的垃圾收集器。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1 java -Xms128m -Xmx2g MyApp
在实际使用过程中,初始化堆内存的大小通常被视为堆内存大小的下界。
然而JVM可以在运行时动态的调整堆内存的大小,所以理论上来说我们有可能会看到堆内存的大小小于初始化堆内存的大小。
但是即使在非常低的堆内存使用下,我也从来没有遇到过这种情况。
这种行为将会方便开发者和系统管理员,因为我们可以通过将“-Xms”和“-Xmx”设置为相同大小来获得一个固定大小的堆内存。
-Xms
和-Xmx实际上是-XX:InitialHeapSize和-XX:MaxHeapSize的缩写。
我们也可以直接使用这两个参数,它们所起得效果是一样的:
1 $ java -XX:InitialHeapSize=128m -XX:MaxHeapSize=2g MyApp
需要注意的是,所有JVM关于初始\最大堆内存大小的输出都是使用它们的完整名称:“InitialHeapSize”和“InitialHeapSize”。
所以当你查询一个正在运行的JVM的堆内存大小时,如使用
-XX:+PrintCommandLineFlags参数或者通过JMX查询,你应该寻找“InitialHeapSize”和“InitialHeapSize”标志而不是“Xms”和“Xmx”。
-XX:+HeapDumpOnOutOfMemoryError and -XX:HeapDumpPath
如果我们没法为-Xmx(最大堆内存)设置一个合适的大小,那么就有可能面临内存溢出(OutOfMemoryError)的风险,这可能是我们使用JVM时面临的最可怕的猛兽之一。
就同另外一篇关于这个主题的博文说的一样,导致内存溢出的根本原因需要仔细的定位。
通常来说,分析堆内存快照(Heap Dump)是一个很好的定位手段,如果发生内存溢出时没有生成内存快照那就实在是太糟了,特别是对于那种JVM已经崩溃或者错误只出现在顺利运行了数小时甚至数天的生产系统上的情况。
幸运的是,我们可以通过设置-XX:+HeapDumpOnOutOfMemoryError 让JVM在发生内存溢出时自动的生成堆内存快照。
有了这个参数,当我们不得不面对内存溢出异常的时候会节约大量的时间。
默认情况下,堆内存快照会保存在JVM的启动目录下名为java_pid<pid>.hprof 的文件里(在这里<pid>就是JVM进程的进程号)。
也可以通过设置-XX:HeapDumpPath=<path>来改变默认的堆内存快照生成路径,<path>可以是相对或者绝对路径。
虽然这一切听起来很不错,但有一点我们需要牢记。
堆内存快照文件有可能很庞大,特别是当内存溢出错误发生的时候。
因此,我们推荐将堆内存快照生成路径指定到一个拥有足够磁盘空间的地方。
-XX:OnOutOfMemoryError
当内存溢发生时,我们甚至可以可以执行一些指令,比如发个E-mail通知管理员或者执行一些清理工作。
通过-XX:OnOutOfMemoryError 这个参数我们可以做到这一点,这个参数可以接受一串指令和它们的参数。
在这里,我们将不会深入它的细节,但我们提供了它的一个例子。
在下面的例子中,当内存溢出错误发生的时候,我们会将堆内存快照写到/tmp/heapdump.hprof 文件并且在JVM的运行目录执行脚本cleanup.sh
1 $ java -XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/tmp/heapdump.hprof -XX:OnOutOfMemoryError ="sh ~/cleanup.sh" MyApp -XX:PermSize and -XX:MaxPermSize
永久代在堆内存中是一块独立的区域,它包含了所有JVM 加载的类的对象表示。
为了成功运行应用程序,JVM 会加载很多类(因为它们依赖于大量的第三方库,而这又依赖于更多的库并且需要从里面将类加载进来)这就需要增加永久代的大小。
我们可以使用-XX:PermSize 和-XX:MaxPermSize 来达到这个目的。
其中-XX:MaxPermSize 用于设置永久代大小的最大值,-XX:PermSize 用于设置永久代初始大小。
下面是一个简单的例子:
1 $ java -XX:PermSize=128m -XX:MaxPermSize=256m MyApp 请注意,这里设置的永久代大小并不会被包括在使用参数-XX:MaxHeapSize 设置的堆内存大小中。
也就是说,通过-XX:MaxPermSize 设置的永久代内存可能会需要由参数-XX:MaxHeapSize 设置的堆内存以外的更多的一些堆内存。
-XX:InitialCodeCacheSize and -XX:ReservedCodeCacheSize
JVM 一个有趣的,但往往被忽视的内存区域是“代码缓存”,它是用来存储已编译方法生成的本地代码。
代码缓存确实很少引起性能问题,但是一旦发生其影响可能是毁灭性的。
如果代码缓存被占满,JVM 会打印出一条警告消息,并切换到interpreted-only 模式:JIT 编译器被停用,字节码将不再会被编译成机器码。
因此,应用程序将继续运行,但运行速度会降低一个数量级,直到有人注意到这个问题。
就像其他内存区域一样,我们可以自定义代码缓存的大小。
相关的参数是-XX:InitialCodeCacheSize 和-XX:ReservedCodeCacheSize ,它们的参数和上面介绍的参数一样,都是字节值。
-XX:+UseCodeCacheFlushing
如果代码缓存不断增长,例如,因为热部署引起的内存泄漏,那么提高代码的缓存大小只会延缓其发生溢出。
为了避免这种情况的发生,我们可以尝试一个有趣的新参数:当代码缓存被填满时让JVM 放弃一些编译代码。
通过使用-XX:+UseCodeCacheFlushing 这个参数,我们至少可以避免当代码缓存被填满的时候JVM 切换到interpreted-only 模式。
不过,我仍建议尽快解决代码缓存问题发生的根本原因,如找出内存泄漏并修复它。