JVM性能调优
- 格式:doc
- 大小:50.00 KB
- 文档页数:3
jvm对元数据区的调优参数
JVM(Java虚拟机)的元数据区是用于存储类元数据的区域,包括类的结构信息、常量池、方法和字段描述等。
对于元数据区的调优参数,我们可以从不同角度来考虑。
首先,元数据区的大小可以通过参数`-XX:MetaspaceSize`和`-XX:MaxMetaspaceSize`来进行调优。
`-XX:MetaspaceSize`用于设置初始的元数据空间大小,而`-XX:MaxMetaspaceSize`用于设置元数据空间的最大大小。
可以根据应用程序的需求和性能表现来调整这些参数,以确保元数据区有足够的空间来存储类的元数据。
其次,可以通过参数`-XX:MinMetaspaceFreeRatio`和`-
XX:MaxMetaspaceFreeRatio`来调整元数据区的空闲空间大小比例。
这些参数用于控制元数据区的收缩行为,可以根据应用程序的内存使用情况来调整这些参数,以避免过度浪费内存或者过度收缩导致性能问题。
此外,还可以通过参数`-XX:MetaspaceReclaimPolicy`来调整元数据区的回收策略。
这个参数用于控制元数据区的回收行为,可以选择不同的策略来平衡内存的使用和回收效率。
除了上述参数之外,还可以通过监控工具来观察元数据区的内存使用情况,比如使用JConsole、VisualVM等工具来监控元数据区的内存占用情况,及时发现内存泄漏或者内存溢出问题,并进行相应的调优。
总之,对于JVM的元数据区调优参数,我们可以从空间大小、空闲空间比例、回收策略等多个方面进行考虑和调整,以确保元数据区能够满足应用程序的需求,并且能够保持良好的性能表现。
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跟踪正运⾏的程序,并将跟踪数据在标准输出输出;适合于开发环境调试。
《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(Java Virtual Machine),那可真是Java世界里的超级大明星呢。
咱今儿就好好唠唠关于JVM的那些事儿。
一、啥是JVM。
JVM啊,就像是Java程序的一个超级大管家。
Java程序想要跑起来,全得靠它呢。
它就像是一个虚拟的小世界,专门给Java代码提供运行的环境。
你想啊,咱们写的Java代码,如果没有JVM,就像小树苗没有土壤一样,根本没法生长。
而且这个JVM还很神奇,它能让Java实现“一次编写,到处运行”的梦想。
不管是在Windows 系统上,还是在Linux或者Mac系统上,只要有对应的JVM,Java程序就能欢快地跑起来。
这就好比是一个万能钥匙,能打开各种系统的大门。
二、JVM的体系结构。
1. 类加载器(ClassLoader)类加载器就像是一个勤劳的小搬运工。
它的任务呢,就是把咱们写好的.class文件加载到JVM里。
这里面还有不同种类的类加载器呢。
有引导类加载器(Bootstrap ClassLoader),这可是类加载器里的老大,它负责加载Java核心类库,就像一个家族里的老祖宗,管着最最重要的东西。
然后还有扩展类加载器(Extension ClassLoader),它主要负责加载Java的扩展库,就像是家族里负责拓展业务的小能手。
最后还有应用程序类加载器(Application ClassLoader),这个就是负责加载咱们自己写的那些类啦,就像是照顾自家孩子的小保姆。
这几个类加载器之间还有个很有趣的关系,就像一个层层递进的小梯队,一个管着一个呢。
2. 运行时数据区(Runtime Data Areas)这个运行时数据区可就像是JVM的大仓库,里面分成好多小房间。
- 堆(Heap)堆啊,那可是JVM里的大仓库,专门用来存放对象实例的。
就像一个超级大的储物间,Java程序里创建的那些对象,都一股脑儿地往这里面放。
不过这个堆也有自己的烦恼,因为如果对象创建得太多,就可能会出现内存不够用的情况,就像储物间堆满了东西,都快放不下啦。
Java中的性能优化有哪些常见方法在 Java 开发中,性能优化是一个至关重要的环节。
随着应用规模的不断扩大和用户需求的日益增长,确保程序能够高效运行、快速响应变得尤为重要。
下面我们就来探讨一下 Java 中的一些常见性能优化方法。
一、算法和数据结构的选择选择合适的算法和数据结构是性能优化的基础。
例如,对于频繁的插入和删除操作,链表可能比数组更合适;对于快速查找操作,哈希表可能比线性搜索更高效。
在实际开发中,需要根据具体的业务需求和数据特点,选择最优的数据结构和算法。
比如,在一个需要快速查找元素是否存在的场景中,如果使用线性搜索,时间复杂度为 O(n),而使用哈希表,平均时间复杂度可以达到O(1)。
这将大大提高程序的执行效率。
二、减少对象创建和销毁在 Java 中,对象的创建和销毁是相对耗费资源的操作。
因此,应尽量减少不必要的对象创建和销毁。
可以通过对象复用、使用对象池等方式来实现。
例如,在一个循环中,如果每次都创建一个新的对象,会导致大量的内存分配和垃圾回收操作。
可以将对象创建放在循环外部,或者使用对象池来重复利用已经创建的对象。
另外,使用基本数据类型代替对象类型也能减少对象创建的开销。
比如,如果只需要存储一个整数,使用`int`类型而不是`Integer`对象。
三、字符串操作的优化字符串操作在很多应用中都非常常见,因此对字符串操作进行优化也能显著提升性能。
避免频繁的字符串拼接操作,因为这会创建新的字符串对象。
可以使用`StringBuilder`或`StringBuffer`类来进行字符串的拼接,它们在内部进行了优化,能够减少对象的创建。
在字符串比较时,如果不需要区分大小写,可以使用`equalsIgnoreCase()`方法,而不是先将字符串转换为小写或大写后再进行比较,这样可以减少额外的字符串转换操作。
四、合理使用缓存缓存是一种常见的性能优化手段。
可以将经常使用的数据或计算结果缓存起来,避免重复计算或重复获取数据。
JVM性能调优监控工具jps、jstack、jmap、jhat、jstat、hprof使用详解J DK本身提供了很多方便的JVM性能调优监控工具,除了集成式的VisualVM和jConsole外,还有jps、jstack、jmap、jhat、jstat、hprof等小巧的工具,本博客希望能起抛砖引玉之用,让大家能开始对JVM性能调优的常用工具有所了解。
现实企业级Java开发中,有时候我们会碰到下面这些问题:OutOfMemoryError,内存不足内存泄露线程死锁锁争用(Lock Contention)Java 进程消耗CPU过高......这些问题在日常开发中可能被很多人忽视(比如有的人遇到上面的问题只是重启服务器或者调大内存,而不会深究问题根源),但能够理解并解决这些问题是Java程序员进阶的必备要求。
本文将对一些常用的JVM 性能调优监控工具进行介绍,希望能起抛砖引玉之用。
A、jps(Java Virtual Machine Process Status Tool) jps 主要用来输出JVM中运行的进程状态信息。
语法格式如下:jps[options] [hostid]如果不指定hostid就默认为当前主机或服务器。
命令行参数选项说明如下:-q 不输出类名、Jar名和传入main方法的参数-m 输出传入main 方法的参数-l 输出main类或Jar的全限名-v 输出传入JVM的参数比如下面:root@ubuntu:/# jps -m -l2458org.artifactory.standalone.main.Main /usr/local/artifactory-2.2.5/etc/jetty.xml29920 com.sun.tools.hat. Main -port 9998 /tmp/dump.dat3149 org.apache.catalina.startup.Boo tstrap start30972 sun.tools.jps.Jps -m -l8247 org.apache.catalin a.startup.Bootstrap start25687com.sun.tools.hat.Main -port 9999 dump.dat21711 mrf-center.jarB、jstack jstack主要用来查看某个Java进程内的线程堆栈信息。
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调优总结作者: 和你在一起程序员其实很痛苦的,每隔一段时间就会听到、看到很多很多新名词、新技术---囧.幸而有了互联网,有了开源、有了wiki、有了分享:)—人人为我,我为人人。
拓荒者走过的时候很痛苦,但是如果能给后来人留下点路标,是不是可以让他们少走一些弯路呢?踏着前辈的足迹我走到了这里,也应该为后来的人留下点东西。
走夜路其实不可怕,可怕的是一个人走夜路:) - 做最棒的软件开发交流社区A-PDF Number Pro DEMO: Purchase from to remove the watermark目 录1. java路上1.1 JVM调优总结-序 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3 1.2 JVM调优总结(一)-- 一些概念 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4 1.3 JVM调优总结(二)-一些概念 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7 1.4 JVM调优总结(三)-基本垃圾回收算法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .9 1.5 JVM调优总结(四)-垃圾回收面临的问题 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .12 1.6 JVM调优总结(五)-分代垃圾回收详述1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .14 1.7 JVM调优总结(六)-分代垃圾回收详述2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .18 1.8 JVM调优总结(七)-典型配置举例1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .26 1.9 JVM调优总结(八)-典型配置举例2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .31 1.10 JVM调优总结(九)-新一代的垃圾回收算法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .34 1.11 JVM调优总结(十)-调优方法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .38 1.12 JVM调优总结(十一)-反思 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .47 1.13 JVM调优总结(十二)-参考资料 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .501.1 JVM调优总结-序发表时间: 2009-11-17几年前写过一篇关于JVM调优的文章,前段时间拿出来看了看,又添加了一些东西。
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是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(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 调优总结常见配置举例堆大小设置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 性能调优⼯具之jmap 命令详解jmap 名称:Java Memory Map (内存映射)官⽅⽂档:https:///javase/1.5.0/docs/tooldocs/share/jmap.html功能描述:内容太多,直接看前辈们的总结:java 命令--jmap 命令使⽤(这篇⽂章写得⾮常好)Java 虚拟机的内存组成以及堆内存介绍Java GC ⼯作原理JVM 内存区域划分Eden Space 、Survivor Space 、Tenured Gen ,Perm Gen 解释JDK,JRE,JVM 区别与联系【JVM 】12_空间分配担保(没看懂?)下⾯是我的⼀个⼩⼩实践:1.使⽤ jmap -dump:format=b,file=filename pid 命令将堆快照⽂件下载到本地1234567[root@hadoop ~]# jmap -dump:format=b,file=/root/heap.hprof 3346 #导出堆快照⽂件Dumping heap to /root/heap.hprof ...Heap dump file created[root@hadoop ~]# ll #查看total 8572-rw------- 1 root root 4365247 Apr 9 08:15 heap.hprof[root@hadoop ~]# sz heap.hprof #将⽂件下载到本地2.使⽤JVM ⾃带的JVisualVM ⼯具查看堆快照⽂件在%JAVA_HOME%/bin ⽬录下双击jvisualvm.exe 打开-->⽂件-->装⼊-->选择Dump ⽂件类型-->找到堆快照⽂件-->打开在类栏中找到你要查看的类名双击进⼊实例数栏-->查看统计出的实例化的对象数⽬,分析对象的引⽤找到是谁在实例化此对象,从⽽找到产⽣⼤对象的原因。
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收集器:并发标记清除算法的收集器,适用于需要较短停顿时间的应用程序。
SpringBootJVM参数调优⽅式⽬录SpringBoot JVM参数调优各种参数SpringBoot jar包启动设置JVM参数配置初始化堆和最⼤堆的⼤⼩SpringBoot JVM参数调优各种参数参数名称含义默认值说明-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是不同的。
整个堆⼤⼩=年轻代⼤⼩ + 年⽼代⼤⼩ + 持久代⼤⼩. 增⼤年轻代后,将会减⼩年⽼代⼤⼩.此值对系统性能影响较⼤,Sun官⽅推荐配置为整个堆的3/8-XX:NewSize设置年轻代⼤⼩(for 1.3/1.4)-XX:MaxNewSize年轻代最⼤值(for 1.3/1.4)-XX:PermSize 设置持久代(perm gen)初始值物理内存的1/64-XX:MaxPermSize设置持久代最⼤值物理内存的1/4-Xss每个线程的堆栈⼤⼩JDK5.0以后每个线程堆栈⼤⼩为1M,以前每个线程堆栈⼤⼩为256K.更具应⽤的线程所需内存⼤⼩进⾏调整.在相同物理内存下,减⼩这个值能⽣成更多的线程.但是操作系统对⼀个进程内的线程数还是有限制的,不能⽆限⽣成,经验值在3000~5000左右⼀般⼩的应⽤,如果栈不是很深,应该是128k够⽤的⼤的应⽤建议使⽤256k。
这个选项对性能影响⽐较⼤,需要严格的测试。
(校长)和threadstacksize选项解释很类似,官⽅⽂档似乎没有解释,在论坛中有这样⼀句话:”” -Xss is translated in a VM flag named ThreadStackSize” ⼀般设置这个值就可以了。
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性能调优
一、引言
本文的读者是技术支持人员。
阅读本文后,你将理解jboss的启动脚本文件(run.sh)中有一系列的JVM配置参数的含义,以及如何调整它们,从而使得MegaEyes中心管理服务器的性能得到优化。
MegaEyes中心管理服务器的性能调优涉及到系统的多个方面,包括MegaEyes应用本身、应用服务器(jboss)、数据库和java虚拟机(JVM)等等。
本文重点介绍JVM的性能优化。
需要注意的是,JVM性能调优具有应用独特性(application specific),就是说,不同的应用情形应该有不同的调整方案,这就要求你首先要观察JVM的运行状态,然后根据观察结果调整参数。
没有一个通用的调优方案可以适用于所有的MegaEyes应用。
什么是性能调优
对性能调优,不同的人有不同的理解,本文是指对下列指标最大化:
⏹并发用户(concurrent users),在服务请求失败或请求响应超过预期时间之前,系
统支持的最大并发用户数量。
⏹系统容量(throughput),可以用每秒处理的事务(transaction)数量计算。
⏹可靠性(reliability)
换句话说,我们想对更多的用户提供更快捷的、不会中断的服务。
JVM性能调优的重点
JVM的性能调优的重点是垃圾回收(gc,garbage collection)和内存管理。
垃圾回收的时候会导致整个虚拟机暂停服务,因此,应该尽可能地缩短垃圾回收的处理时间。
JVM内存
JVM占用的内存称为堆(heap),它被分为三个区:年轻(young,又称为new)、老(tenured,又称为old)和永生(perm)。
这三个区是按照java对象的生存期划分的,在new区的对象生存期最短,很快就会被gc回收;perm区的对象生存期最长,与JVM同生死。
Perm区的对象不会被gc回收。
new区又被分为三个部分:伊甸园(eden)和两个幸存者(survivor)。
对象的创建总是在eden部分(这大概就是命名该部分为eden的原因吧)。
两个survivor中总有一个是空的,它作为另一个survivor的缓冲区。
当gc发生时,所有eden和survivor中活下来的对象被移动到另一个survivor中。
对象会在两个survivor之间不断移动,直到活得足够久,然后移动到old区。
我们可以猜想,之所以如此划分使用内存,肯定是为了缩短gc的执行时间,提
高gc的执行效率。
垃圾回收算法
除了默认的垃圾回收算法外,JVM还提供了两个:并行(parallel)和并发(concurrent),前者作用在new区,后者作用在old区。
两者可以同时使用。
并行算法会产生多个线程以提高执行效率。
当有多个cpu的时候,它会显著缩短gc的工作时间。
并发算法可以在JVM不中断对应用的服务的情况下执行(通常情况下,在gc工作的时候JVM停止对应用的服务)。
二、性能参数
比较大的。
三、性能参数调优
要调整参数首先要观察它们。
观察JVM内存和gc的工具很多,jdk本身也提供了一些,这些工具简单、实用,而且不需要安装。
其中,最常用的是jps和jstat,前者用来查看JVM 的进程id(pid),后者用这个pid作为参数来得到内存和gc的状态,就是说,在执行jstat 之前必须用jps得到JVM的pid。
Jstat的例子::
jstat -gcutil 21308 250 10
其中,21308是(运行jboss)的JVM的pid;250是采样间隔,单位是毫秒,即250毫秒采集一次数据;10是采样次数。
上述命令的执行结果如下:
S0 S1 E O P YGC YGCT FGC FGCT GCT
0.00 0.00 11.39 5.29 13.57 328 1.955 327 133.126 135.081
0.00 0.00 11.39 5.29 13.57 328 1.955 327 133.126 135.081
0.00 0.00 11.39 5.29 13.57 328 1.955 327 133.126 135.081
0.00 0.00 11.39 5.29 13.57 328 1.955 327 133.126 135.081
0.00 0.00 11.39 5.29 13.57 328 1.955 327 133.126 135.081
0.00 0.00 11.39 5.29 13.57 328 1.955 327 133.126 135.081
0.00 0.00 11.39 5.29 13.57 328 1.955 327 133.126 135.081
0.00 0.00 11.39 5.29 13.57 328 1.955 327 133.126 135.081
0.00 0.00 11.39 5.29 13.57 328 1.955 327 133.126 135.081
0.00 0.00 11.39 5.29 13.57 328 1.955 327 133.126 135.081
我们可以将采样次数设置足够大,这样就可以看到内存和gc的变化了。
从上述数据可以看出,内存各区域的占用率都不高,gc的执行时间都不长,不过,perm 区有些太大,太浪费了。
因为perm区的对象与JVM的生命周期是一样的,对象数量不会动态变化,所以,我们可以把这个区域的尺寸设置为原尺寸的二分之一,这样,perm的占用率将从13%左右增加到26%左右。
从上述数据还可以看出,new区的gc明显比真个heap的gc快得多。
通常,FGC应该不超过400毫秒,否则,将严重影响java应用的正常运行。
参考文档
全球眼平台调优方案.doc。