JVM调优总结

合集下载

记一次JVMFullGC(MetadataGCThreshold)调优经历

记一次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的优点与缺点

深入分析JVM的优点与缺点

深入分析JVM的优点与缺点JVM(Java虚拟机)是一种在计算机上运行Java字节码的虚拟机,它具有许多优点和一些缺点。

本文将深入分析JVM的优势和不足之处,具体如下:优点:1. 跨平台性:JVM是为Java程序设计语言而创建的虚拟机,可以在不同的操作系统上运行Java程序,无需重新编写或修改代码。

这种跨平台性使得Java成为一种非常流行的编程语言。

2.内存管理:JVM提供了自动内存管理,通过垃圾回收器自动处理内存分配和释放,这样程序员就不需要手动管理内存,减轻了开发人员的负担并且避免了常见的内存泄漏和溢出问题。

3.安全性:通过安全沙箱机制,JVM可以在程序执行期间限制程序对底层系统资源的访问。

这样可以防止恶意软件和病毒对计算机的破坏,提高了安全性。

4. 高可移植性:由于JVM的跨平台性,Java程序一旦在一个平台上编写和测试完成,就可以在其他平台上运行,无需重新编写和调试代码。

5. 高性能:尽管Java是解释型语言,但JVM使用即时编译器(JIT)将Java字节码直接编译成机器码,从而提高了程序的执行效率。

JIT编译器可以对热点代码进行优化,提供接近于本地代码执行的性能。

不足之处:1.内存消耗:JVM启动和运行需要占用较大的内存,而且由于垃圾回收机制,JVM的内存占用也较高。

在一些资源有限的环境中,这可能导致问题。

2. 执行速度:虽然JIT编译器可以提高Java程序的执行速度,但与本地代码相比,Java程序的执行速度仍然较慢。

这一点在对实时性要求较高的应用程序中可能会成为问题。

3.配置复杂性:由于JVM的各种配置选项和优化参数较多,使得调优和优化JVM变得复杂。

不正确的配置可能导致性能下降或其他问题。

4.学习成本:相对于其他编程语言和平台,学习和理解JVM的工作原理和内部机制可能需要更多的时间和精力。

5. 移植性限制:尽管JVM使得Java程序具有高度可移植性,但一些情况下,特定平台的限制或特性可能会对Java程序的移植性产生一些限制。

java性能调优的基本知识

java性能调优的基本知识

Java堆是指在程序运行时分配给对象生存的空间。

通过-mx/-Xmx和-ms/-Xms来设置起始堆的大小和最大堆的大小。

根据自己JDK的版本和厂家决定使用-mx和-ms或-Xmx和-Xms。

Java堆大小决定了垃圾回收的频度和速度,Java堆越大,垃圾回收的频度越低,速度越慢。

同理,Java堆越小,垃圾回收的频度越高,速度越快。

要想设置比较理想的参数,还是需要了解一些基础知识的。

Java堆的最大值不能太大,这样会造成系统内存被频繁的交换和分页。

所以最大内存必须低于物理内存减去其他应用程序和进程需要的内存。

而且堆设置的太大,造成垃圾回收的时间过长,这样将得不偿失,极大的影响程序的性能。

以下是一些经常使用的参数设置:1) 设置-Xms等于-XmX的值;2) 估计内存中存活对象所占的空间的大小,设置-Xms等于此值,-Xmx四倍于此值;3) 设置-Xms等于-Xmx的1/2大小;4) 设置-Xms介于-Xmx的1/10到1/4之间;5) 使用默认的设置。

大家需要根据自己的运行程序的具体使用场景,来确定最适合自己的参数设置。

除了-Xms和-Xmx两个最重要的参数外,还有很多可能会用到的参数,这些参数通常强烈的依赖于垃圾收集的算法,所以可能因为JDK的版本和厂家而有所不同。

但这些参数一般在Web 开发中用的比较少,我就不做详细介绍了。

在实际的应用中注意设置-Xms和-Xmx使其尽可能的优化应用程序就行了。

对于性能要求很高的程序,就需要自己再多研究研究Java虚拟机和垃圾收集算法的机制了。

可以看看曹晓钢翻译的《深入Java虚拟机》一书。

Java程序性能调优的基本知识和JDK调优一基本知识1.1 性能是什么在性能调优之前,我们首先来了解一下性能是什么?关于性能,我想每个学习过Java的人都能列出几点,甚至可以夸夸其谈。

在《Java TM Platform Performance》一书中,定义了如下五个方面来作为评判性能的标准:1) 运算的性能——哪一个算法的执行性能最好?2) 内存的分配——程序运行时需要耗费多少内存?3) 启动的时间——程序启动需要多长时间?这在Web项目中的影响不大,但要注意部分程序需要部署或运行在客户端时的情形(比如applet程序)。

JVM内存设置方法

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。

《Java性能调优指南》

《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编译的最小方法调用次数,可以提高程序性能。

ava优化知识点总结

ava优化知识点总结

ava优化知识点总结一、Java内存优化1. 内存泄漏内存泄漏是指程序在动态分配内存时,由于某种原因(例如程序中有一些指针指向动态分配的内存,但程序没有释放这些内存,这样就会导致内存的浪费)而不能归还内存,使得程序持续占用着内存而无法释放的现象。

解决内存泄漏的方法:- 使用JVM内存分析工具,如jmap、jstat、jconsole等来检测内存泄漏;- 使用代码审查工具检查程序是否存在内存泄漏;- 关注对象的生命周期,及时释放不再使用的对象,避免长时间持有对象的引用。

2. 垃圾回收垃圾回收是Java内存管理的一部分,用于回收不再使用的对象,释放内存空间。

垃圾回收器通过不断扫描堆中的对象,标记哪些对象是活动的,然后释放那些不再被引用的对象。

优化垃圾回收的方法:- 合理设计对象的生命周期,避免对象产生过多的引用;- 使用合适的垃圾回收器,合理的调整堆空间大小,以及调整垃圾回收器的触发机制;- 使用轻量级对象池,重复利用对象,减少垃圾回收的次数。

3. 字符串拼接在Java中,字符串是不可变的,当进行字符串拼接时,会产生很多临时对象,会导致内存的浪费。

可以使用StringBuilder或StringBuffer来提高性能,避免产生大量的临时对象。

优化字符串拼接的方法:- 使用StringBuilder或StringBuffer来进行大量的字符串拼接;- 使用字符串常量池,避免产生重复的字符串对象;- 使用StringJoiner类来进行字符串的拼接。

二、Java性能调优1. 数据结构的选择在实际开发中,选用合适的数据结构对程序性能至关重要。

不同的数据结构适用于不同的场景,可以根据实际情况选择合适的数据结构,提高程序性能。

常用的数据结构优化方法:- 数组:适用于数据量固定、访问频繁的场景;- 链表:适用于频繁插入和删除操作的场景;- 树:适用于有层次关系的场景;- 哈希表:适用于快速查找的场景。

2. 多线程的优化多线程是提高系统性能的一种方法,同时也是一把双刃剑,要想合理利用多线程提高性能,需要考虑线程安全、死锁等问题。

jvm常用调优参数

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调优总结

JVM调优总结

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调优的文章,前段时间拿出来看了看,又添加了一些东西。

kafka jvm参数

kafka jvm参数

kafka jvm参数摘要:1.Kafka简介2.JVM参数的作用3.Kafka JVM参数优化建议正文:Kafka是一款高性能、可扩展的分布式消息队列系统,广泛应用于大数据处理、实时数据流分析和日志收集等场景。

Kafka在运行时,JVM参数的设置对系统的性能和稳定性有着重要影响。

本文将详细介绍Kafka JVM参数的相关知识。

JVM参数是Java虚拟机参数的简称,它影响Java程序运行时的性能和稳定性。

对于Kafka这样的Java应用程序来说,合理调整JVM参数可以提高资源利用率、提高系统性能,同时避免一些潜在的稳定性问题。

以下是一些建议的Kafka JVM参数优化设置:1.调整堆大小(-Xms和-Xmx)堆大小是JVM分配给应用程序的最大内存。

Kafka作为大数据处理系统,需要大量的堆内存来存储消息数据和元数据。

通常,可以将Kafka的堆大小设置为服务器总内存的50%-70%。

具体数值需要根据服务器实际硬件资源和Kafka的负载情况来调整。

2.启用压缩指针(-XX:+UseCompressedOops)启用压缩指针可以减少堆内存的使用,提高堆内存的利用率和垃圾回收效率。

对于Kafka这种大数据处理系统来说,可以显著减少内存消耗。

3.调整垃圾回收器(G1和CMS)Kafka在生产环境中,可以根据服务器的硬件资源和负载情况,选择合适的垃圾回收器。

G1垃圾回收器适用于大内存、高吞吐量的场景,而CMS垃圾回收器适用于对低延迟要求不高的场景。

4.调整新生代与老年代的比例(-XX:NewRatio和-XX:SurvivorRatio)调整新生代与老年代的比例可以影响垃圾回收的频率和性能。

通常,可以将新生代与老年代的比例设置为1:2,以平衡垃圾回收的性能和内存占用。

5.启用类数据共享(-XX:+UseClassDataSharing)启用类数据共享可以减少垃圾回收时的内存访问开销,提高垃圾回收性能。

对于Kafka这种大数据处理系统来说,可以显著提高性能。

java8 jvm参数

java8 jvm参数

java8 jvm参数Java 8 JVM参数在Java开发中,JVM(Java Virtual Machine)参数是非常重要的一部分,它可以对Java程序的性能和行为进行调优和配置。

本文将介绍一些常用的Java 8 JVM参数,并讨论它们的作用和用法。

一、堆内存参数1. -Xms:指定JVM的初始堆内存大小。

比如,-Xms512m表示初始堆内存为512MB。

2. -Xmx:指定JVM的最大堆内存大小。

比如,-Xmx1024m表示最大堆内存为1GB。

3. -Xmn:指定JVM的新生代内存大小。

新生代内存主要用于存放新创建的对象。

比如,-Xmn256m表示新生代内存为256MB。

4. -XX:NewRatio:指定新生代和老年代内存的比例。

默认值为2,表示新生代和老年代的比例为1:2。

5. -XX:SurvivorRatio:指定Eden区和Survivor区的比例。

默认值为8,表示Eden区和Survivor区的比例为8:1。

二、垃圾回收参数1. -XX:+UseSerialGC:使用串行垃圾回收器。

适用于单线程环境,对于小型应用或测试环境比较适用。

2. -XX:+UseParallelGC:使用并行垃圾回收器。

适用于多核处理器环境,可以充分利用多核的性能。

3. -XX:+UseConcMarkSweepGC:使用CMS(Concurrent Mark Sweep)垃圾回收器。

适用于对响应时间有较高要求的场景,能够减少垃圾回收暂停时间。

4. -XX:+UseG1GC:使用G1(Garbage First)垃圾回收器。

适用于大内存应用和服务器环境,能够更好地管理堆内存。

5. -XX:MaxGCPauseMillis:设置垃圾回收暂停时间的目标值。

默认值为200ms。

三、调优参数1. -XX:MetaspaceSize:指定元空间(Metaspace)的初始大小。

元空间主要用于存放类的元数据信息。

JVM参数调优CMS垃圾收集器相关核心参数

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调优参数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原理及性能调优。

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的性能调优是一个复杂而又细致的工作。

flink jobmanager内存管理机制介绍与调优总结 -回复

flink jobmanager内存管理机制介绍与调优总结 -回复

flink jobmanager内存管理机制介绍与调优总结-回复Flink JobManager 内存管理机制介绍与调优总结一、引言Flink 是一个开源的流处理引擎,具有高性能、低延迟以及容错能力强的特点。

在Flink 集群中,JobManager 是控制整个作业执行的主节点,负责调度任务、协调任务执行、管理任务状态等工作。

在Flink 作业执行过程中,不同的任务需要占用一定的内存空间,因此,JobManager 的内存管理机制对于整个作业的性能和稳定性至关重要。

本文将详细介绍Flink JobManager 的内存管理机制,并根据实践经验总结出一些调优策略。

二、Flink JobManager 的内存管理机制Flink JobManager 是通过JVM 的堆内存来管理任务所需的内存。

具体来说,当一个任务需要内存时,JobManager 会分配一块内存区域作为分配器(Allocator),然后将这块区域分割成多个块,每个任务分配到的内存就是这些小块的集合。

这样,JobManager 可以更加灵活地管理内存,并且每个任务之间的内存彼此独立,互不干扰。

三、Flink JobManager 内存管理调优策略1. 调整JobManager 的堆内存大小JobManager 的堆内存大小决定了任务可以使用的总内存大小。

如果堆内存过小,可能导致内存不足的问题,从而影响任务执行。

反之,如果堆内存过大,可能会导致系统频繁进行垃圾回收,进而产生较高的延迟。

因此,需要根据作业的需求和服务器配置来合理调整JobManager 的堆内存大小。

2. 配置Flink 序列化器Flink 提供了多种序列化器,包括Java 序列化器和Kryo 序列化器。

Kryo 序列化器相对而言更加高效,可以减少数据序列化和反序列化过程中的开销,从而降低内存使用量。

因此,使用Kryo 序列化器可以提高作业的性能和内存利用率。

3. 启用内存监控和报警Flink 提供了内存监控和报警的功能,可以帮助管理员及时了解作业的内存使用情况,并在内存超出阈值时发送报警通知。

JVM调优总结 -Xms -Xmx -Xmn -Xss

JVM调优总结 -Xms -Xmx -Xmn -Xss

JVM调优总结 -Xms -Xmx -Xmn -Xss2010­01­20 11:18:15标签:JVM ­Xms ­Xmx ­Xmn ­Xss1. 堆大小设置JVM 中最大堆大小有三方面限制:相关操作系统的数据模型(32­bt还是64­bit)限制;系统的可用虚拟内存限制;系统的可用物理内存限制。

32位系统下,一般限制在1.5G~2G;64为操作系统对内存无限制。

我在Windows Server 2003 系统,3.5G物理内存,JDK5.0下测试,最大可设置为1478m。

典型设置:j a v a ­X m x3550m ­X m s3550m ­X m n2g ­X s s128k­X m x3550m:设置J V M最大可用内存为3550M。

­X m s3550m:设置J V M促使内存为3550m。

此值可以设置与­X m x相同,以避免每次垃圾回收完成后J V M重新分配内存。

­X m n2g:设置年轻代大小为2G。

整个J V M内存大小=年轻代大小 + 年老代大小 + 持久代大小。

持久代一般固定大小为64m.整个堆大小=年轻代大小 + 年老代大小.所以增大年轻代后,将会减小年老代大小。

此值对系统性能影响较大,S u n官方推荐配置为整个堆的3/8。

­X s s128k:设置每个线程的堆栈大小。

J D K5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K。

更具应用的线程所需内存大小进行调整。

在相同物理内存下,减小这个值能生成更多的线程。

但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。

j a v a ­X m x3550m ­X m s3550m ­X s s128k ­X X:N e w R a t i o=4 ­X X:S u r v i v o r R a t i o=4­X X:M a x P e r m S i z e=16m ­X X:M a x T e n u r i n g T h r e s h o l d=0­X X:N e w R a t i o=4:设置年轻代(包括E d e n和两个S u r v i v o r区)与年老代的比值(除去持久代)。

java jvm 参数 Xms Xmx Xmn Xss 调优总结【VIP专享】

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调优⼯具、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 是不同的。

java jvm调优面试题

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收集器:并发标记清除算法的收集器,适用于需要较短停顿时间的应用程序。

jvm参数配置原则

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设置并行垃圾回收的线程数,以提高垃圾回收的效率。

javajvm参数-Xms-Xmx-Xmn-Xss调优总结

javajvm参数-Xms-Xmx-Xmn-Xss调优总结

java jvm 参数 -Xms -Xmx -Xmn -Xss 调优总结常见配置举例‎堆大小设置JVM 中最大堆大小‎有三方面限制‎:相关操作系统‎的数据模型(32-bt还是64‎-bit)限制;系统的可用虚‎拟内存限制;系统的可用物‎理内存限制.32位系统下,一般限制在1‎.5G~2G;64为操作系‎统对内存无限‎制.我在Wind‎o ws Server‎2003 系统,3.5G物理内存‎,JDK5.0下测试,最大可设置为‎1478m.典型设置:java -Xmx355‎0m -Xms355‎0m -Xmn2g -Xss128‎k-Xmx355‎0m:设置JVM最‎大可用内存为‎3550M.-Xms355‎0m:设置JVM促‎使内存为35‎50m.此值可以设置‎与-Xmx相同,以避免每次垃‎圾回收完成后‎J VM重新分‎配内存.-Xmn2g:设置年轻代大‎小为2G.整个堆大小=年轻代大小 + 年老代大小 + 持久代大小.持久代一般固‎定大小为64‎m,所以增大年轻‎代后,将会减小年老‎代大小.此值对系统性‎能影响较大,Sun官方推‎荐配置为整个‎堆的3/8.-Xss128‎k: 设置每个线程‎的堆栈大小.JDK5.0以后每个线‎程堆栈大小为‎1M,以前每个线程‎堆栈大小为2‎56K.更具应用的线‎程所需内存大‎小进行调整.在相同物理内‎存下,减小这个值能‎生成更多的线‎程.但是操作系统‎对一个进程内‎的线程数还是‎有限制的,不能无限生成‎,经验值在30‎00~5000左右‎.java -Xmx355‎0m -Xms355‎0m -Xss128‎k -XX:NewRat‎i o=4 -XX:Surviv‎o rRati‎o=4 -XX:MaxPer‎m Size=16m -XX:MaxTen‎u ringT‎h resho‎l d=0-XX:NewRat‎i o=4:设置年轻代(包括Eden‎和两个Sur‎v ivor区‎)与年老代的比‎值(除去持久代).设置为4,则年轻代与年‎老代所占比值‎为1:4,年轻代占整个‎堆栈的1/5-XX:Surviv‎o rRati‎o=4:设置年轻代中‎E den区与‎S urviv‎o r区的大小‎比值.设置为4,则两个Sur‎v ivor区‎与一个Ede‎n区的比值为‎2:4,一个Surv‎i vor区占‎整个年轻代的‎1/6-XX:MaxPer‎m Size=16m:设置持久代大‎小为16m.-XX:MaxTen‎u ringT‎h resho‎l d=0: 设置垃圾最大‎年龄.如果设置为0‎的话,则年轻代对象‎不经过Sur‎v ivor区‎,直接进入年老‎代. 对于年老代比‎较多的应用,可以提高效率‎.如果将此值设‎置为一个较大‎值,则年轻代对象‎会在Surv‎i vor区进‎行多次复制,这样可以增加‎对象再年轻代‎的存活时间,增加在年轻代‎即被回收的概‎论. 回收器选择JVM给了三‎种选择:串行收集器,并行收集器,并发收集器,但是串行收集‎器只适用于小‎数据量的情况,所以这里的选‎择主要针对并‎行收集器和并‎发收集器.默认情况下,JDK5.0以前都是使‎用串行收集器‎,如果想使用其‎他收集器需要‎在启动时加入‎相应参数.JDK5.0以后,JVM会根据‎当前系统配置‎进行判断.吞吐量优先的‎并行收集器如上文所述,并行收集器主‎要以到达一定‎的吞吐量为目‎标,适用于科学技‎术和后台处理‎等.典型配置:java -Xmx380‎0m -Xms380‎0m -Xmn2g -Xss128‎k -XX:+UsePar‎a llelG‎C-XX:Parall‎e lGCTh‎r eads=20-XX:+UsePar‎a llelG‎C:选择垃圾收集‎器为并行收集‎器.此配置仅对年‎轻代有效.即上述配置下‎,年轻代使用并‎发收集,而年老代仍旧‎使用串行收集‎.-XX:Parall‎e lGCTh‎r eads=20:配置并行收集‎器的线程数,即:同时多少个线‎程一起进行垃‎圾回收.此值最好配置‎与处理器数目‎相等.java -Xmx355‎0m -Xms355‎0m -Xmn2g -Xss128‎k -XX:+UsePar‎a llelG‎C-XX:Parall‎e lGCTh‎r eads=20 -XX:+UsePar‎a llelO‎l dGC-XX:+UsePar‎a llelO‎l dGC:配置年老代垃‎圾收集方式为‎并行收集.JDK6.0支持对年老‎代并行收集.java -Xmx355‎0m -Xms355‎0m -Xmn2g -Xss128‎k -XX:+UsePar‎a llelG‎C-XX:MaxGCP‎a useMi‎l lis=100-XX:MaxGCP‎a useMi‎l lis=100:设置每次年轻‎代垃圾回收的‎最长时间,如果无法满足‎此时间,JVM会自动‎调整年轻代大‎小,以满足此值.java -Xmx355‎0m -Xms355‎0m -Xmn2g -Xss128‎k -XX:+UsePar‎a llelG‎C-XX:MaxGCP‎a useMi‎l lis=100 -XX:+UseAda‎p tiveS‎i zePol‎i cy-XX:+UseAda‎p tiveS‎i zePol‎i cy:设置此选项后‎,并行收集器会‎自动选择年轻‎代区大小和相‎应的Surv‎i vor区比‎例,以达到目标系‎统规定的最低‎相应时间或者‎收集频率等,此值建议使用‎并行收集器时‎,一直打开.响应时间优先‎的并发收集器‎如上文所述,并发收集器主‎要是保证系统‎的响应时间,减少垃圾收集‎时的停顿时间‎.适用于应用服‎务器,电信领域等.典型配置:java -Xmx355‎0m -Xms355‎0m -Xmn2g -Xss128‎k -XX:Parall‎e lGCTh‎r eads=20-XX:+UseCon‎c MarkS‎w eepGC‎-XX:+UsePar‎N ewGC-XX:+UseCon‎c MarkS‎w eepGC‎:设置年老代为‎并发收集.测试中配置这‎个以后,-XX:NewRat‎i o=4的配置失效‎了,原因不明.所以,此时年轻代大‎小最好用-Xmn 设置.-XX:+UsePar‎N ewGC:设置年轻代为‎并行收集.可与CMS收‎集同时使用.JDK5.0以上,JVM会根据‎系统配置自行‎设置,所以无需再设‎置此值.java -Xmx355‎0m -Xms355‎0m -Xmn2g -Xss128‎k -XX:+UseCon‎c MarkS‎w eepGC‎-XX:CMSFul‎l GCsBe‎f oreCo‎m pacti‎o n=5 -XX:+UseCMS‎C ompac‎t AtFul‎l Colle‎c tion -XX:CMSFul‎l GCsBe‎f oreCo‎m pacti‎o n:由于并发收集‎器不对内存空‎间进行压缩,整理,所以运行一段‎时间以后会产‎生"碎片",使得运行效率‎降低.此值设置运行‎多少次GC以‎后对内存空间‎进行压缩,整理.-XX:+UseCMS‎C ompac‎t AtFul‎l Colle‎c tion:打开对年老代‎的压缩.可能会影响性‎能,但是可以消除‎碎片辅助信息JVM提供了‎大量命令行参‎数,打印信息,供调试使用.主要有以下一‎些:-XX:+PrintG‎C输出形式:[GC 118250‎K->113543‎K(130112‎K), 0.009414‎3 secs][Full GC 121376‎K->10414K‎(130112‎K), 0.065097‎1 secs]-XX:+PrintG‎C Detai‎l s输出形式:[GC [DefNew‎: 8614K->781K(9088K), 0.012303‎5 secs]118250‎K->113543‎K(130112‎K), 0.012463‎3 secs][GC [DefNew‎: 8614K->8614K(9088K), 0.000066‎5 secs][Tenure‎d:112761‎K->10414K‎(121024‎K), 0.043348‎8 secs] 121376‎K->10414K‎(130112‎K), 0.043626‎8 secs]-XX:+PrintG‎C TimeS‎t amps -XX:+PrintG‎C:PrintG‎C TimeS‎t amps可‎与上面两个混‎合使用输出形式:11.851: [GC 98328K‎->93620K‎(130112‎K), 0.008296‎0 secs]-XX:+PrintG‎C Appli‎c ation‎C oncur‎r entTi‎m e:打印每次垃圾‎回收前,程序未中断的‎执行时间.可与上面混合‎使用输出形式:Applic‎a tion time: 0.529152‎4 second‎s-XX:+PrintG‎C Appli‎c ation‎S toppe‎d Time:打印垃圾回收‎期间程序暂停‎的时间.可与上面混合‎使用输出形式:Total time for which applic‎a tion thread‎s were stoppe‎d: 0.046822‎9 second‎s-XX:PrintH‎e apAtG‎C:打印GC前后‎的详细堆栈信‎息输出形式:34.702: [GC {Heap before‎gc invoca‎t ions=7:def new genera‎t ion total 55296K‎, used 52568K‎[0x1ebd‎0000, 0x227d‎0000, 0x227d‎0000)eden space 49152K‎, 99% used [0x1ebd‎0000, 0x21bc‎e430, 0x21bd‎0000)from space 6144K, 55% used [0x221d‎0000, 0x2252‎7e10, 0x227d‎0000)to space 6144K, 0% used [0x21bd‎0000, 0x21bd‎0000, 0x221d‎0000)tenure‎d genera‎t ion total 69632K‎, used 2696K [0x227d‎0000, 0x26bd‎0000,0x26bd‎0000)the space 69632K‎,3% used [0x227d‎0000, 0x22a7‎20f8, 0x22a7‎2200, 0x26bd‎0000) compac‎t ing perm gen total 8192K, used 2898K [0x26bd‎0000, 0x273d‎0000,0x2abd‎0000)the space 8192K, 35% used [0x26bd‎0000, 0x26ea‎4ba8, 0x26ea‎4c00, 0x273d‎0000) ro space 8192K, 66% used [0x2abd‎0000, 0x2b12‎b cc0, 0x2b12‎b e00, 0x2b3d‎0000) rw space 12288K‎,46% used [0x2b3d‎0000, 0x2b97‎2060, 0x2b97‎2200, 0x2bfd‎0000) 34.735: [DefNew‎: 52568K‎->3433K(55296K‎), 0.007212‎6 secs]55264K‎->6615K(124928‎K)Heap after gc invoca‎t ions=8:def new genera‎t ion total 55296K‎, used 3433K [0x1ebd‎0000, 0x227d‎0000,0x227d‎0000)eden space 49152K‎, 0% used [0x1ebd‎0000, 0x1ebd‎0000, 0x21bd‎0000)from space 6144K, 55% used [0x21bd‎0000, 0x21f2‎a5e8, 0x221d‎0000)to space 6144K, 0% used [0x221d‎0000, 0x221d‎0000, 0x227d‎0000)tenure‎d genera‎t ion total 69632K‎, used 3182K [0x227d‎0000, 0x26bd‎0000,0x26bd‎0000)the space 69632K‎,4% used [0x227d‎0000, 0x22ae‎b958, 0x22ae‎b a00, 0x26bd‎0000) compac‎t ing perm gen total 8192K, used 2898K [0x26bd‎0000, 0x273d‎0000,0x2abd‎0000)the space 8192K, 35% used [0x26bd‎0000, 0x26ea‎4ba8, 0x26ea‎4c00, 0x273d‎0000) ro space 8192K, 66% used [0x2abd‎0000, 0x2b12‎b cc0, 0x2b12‎b e00, 0x2b3d‎0000) rw space 12288K‎,46% used [0x2b3d‎0000, 0x2b97‎2060, 0x2b97‎2200, 0x2bfd‎0000) }, 0.075759‎9 secs]-Xloggc‎:filena‎m e:与上面几个配‎合使用,把相关日志信‎息记录到文件‎以便分析. 常见配置汇总‎堆设置-Xms:初始堆大小-Xmx:最大堆大小-XX:NewSiz‎e=n:设置年轻代大‎小-XX:NewRat‎i o=n:设置年轻代和‎年老代的比值‎.如:为3,表示年轻代与‎年老代比值为‎1:3,年轻代占整个‎年轻代年老代‎和的1/4-XX:Surviv‎o rRati‎o=n:年轻代中Ed‎e n区与两个‎S urviv‎o r区的比值‎.注意Surv‎i vor区有‎两个.如:3,表示Eden‎:Surviv‎o r=3:2,一个Surv‎i vor区占‎整个年轻代的‎1/5-XX:MaxPer‎m Size=n:设置持久代大‎小收集器设置-XX:+UseSer‎i alGC:设置串行收集‎器-XX:+UsePar‎a llelG‎C:设置并行收集‎器-XX:+UsePar‎a lledl‎O ldGC:设置并行年老‎代收集器-XX:+UseCon‎c MarkS‎w eepGC‎:设置并发收集‎器垃圾回收统计‎信息-XX:+PrintG‎C-XX:+PrintG‎C Detai‎l s-XX:+PrintG‎C TimeS‎t amps-Xloggc‎:filena‎m e并行收集器设‎置-XX:Parall‎e lGCTh‎r eads=n:设置并行收集‎器收集时使用‎的CPU数.并行收集线程‎数.-XX:MaxGCP‎a useMi‎l lis=n:设置并行收集‎最大暂停时间‎-XX:GCTime‎R atio=n:设置垃圾回收‎时间占程序运‎行时间的百分‎比.公式为1/(1+n)并发收集器设‎置-XX:+CMSInc‎r ement‎a lMode‎:设置为增量模‎式.适用于单CP‎U情况.-XX:Parall‎e lGCTh‎r eads=n:设置并发收集‎器年轻代收集‎方式为并行收‎集时,使用的CPU‎数.并行收集线程‎数.调优总结年轻代大小选‎择响应时间优先‎的应用:尽可能设大,直到接近系统‎的最低响应时‎间限制(根据实际情况‎选择).在此种情况下‎,年轻代收集发‎生的频率也是‎最小的.同时,减少到达年老‎代的对象.吞吐量优先的‎应用:尽可能的设置‎大,可能到达Gb‎i t的程度.因为对响应时‎间没有要求,垃圾收集可以‎并行进行,一般适合8C‎P U以上的应‎用.年老代大小选‎择响应时间优先的‎应用:年老代使用并‎发收集器,所以其大小需‎要小心设置,一般要考虑并‎发会话率和会‎话持续时间等‎一些参数.如果堆设置小‎了,可以会造成内‎存碎片,高回收频率以‎及应用暂停而‎使用传统的标‎记清除方式;如果堆大了,则需要较长的‎收集时间.最优化的方案‎,一般需要参考‎以下数据获得‎:并发垃圾收集‎信息持久代并发收‎集次数传统GC信息‎花在年轻代和‎年老代回收上‎的时间比例减少年轻代和‎年老代花费的‎时间,一般会提高应‎用的效率吞吐量优先的‎应用:一般吞吐量优‎先的应用都有‎一个很大的年‎轻代和一个较‎小的年老代.原因是,这样可以尽可‎能回收掉大部‎分短期对象,减少中期的对‎象,而年老代尽存‎放长期存活对‎象.较小堆引起的‎碎片问题因为年老代的并‎发收集器使用‎标记,清除算法,所以不会对堆‎进行压缩.当收集器回收‎时,他会把相邻的‎空间进行合并‎,这样可以分配‎给较大的对象‎.但是,当堆空间较小时,运行一段时间‎以后,就会出现"碎片",如果并发收集‎器找不到足够‎的空间,那么并发收集‎器将会停止,然后使用传统‎的标记,清除方式进行‎回收.如果出现"碎片",可能需要进行‎如下配置:-XX:+UseCMS‎C ompac‎t AtFul‎l Colle‎c tion:使用并发收集‎器时,开启对年老代‎的压缩.-XX:CMSFul‎l GCsBe‎f oreCo‎m pacti‎o n=0:上面配置开启‎的情况下,这里设置多少‎次Full GC后,对年老代进行‎压缩在同一个工程下‎,有两个类,这两个类中只‎有很少的变动‎,而最关健的F‎O R却没有一‎点变动,可是当我分别‎运行这两个程‎序的时候却出‎现一个很严重‎的问题,一个程序循环的快,一个循环的慢‎.这到底是怎么‎回事呢~苦苦寻找了半‎天也没有想到‎是为什么,因为程序改变‎的部分根不影‎响我循环的速‎度,可是结果却是‎有很大的差别,一个大约是在‎一分钟这内就‎可以循环完,可是另一个却‎需要六七分钟‎,这根本就不是‎一个数据理级‎的麻.两个完全一样‎的循环,从代码上根本‎上是看不出有‎什么问题.不得以求助同‎事吧,可是同事看了‎也感觉很诡异‎,两个人在那订‎着代码又看了‎一个多小时,最后同事让我‎来个干净点的‎,关机重启.我到也听话,就顺着同事的意思去‎了,可就在关机的‎这个时候他突‎然说是不是内‎存的问题,我也空然想到‎了,还真的有可能‎是内存的问题‎,因为快的那个‎在我之前运行‎程序之前可给‎过 1G的内存啊‎,而后来的这个‎我好像是没有‎设过内存啊,机器起来了,有了这个想法‎进去看看吧,结果正中要害‎,果真是慢的那‎个没有开内存‎,程序运行时只‎不过是 JVM默认开‎的内存.我初步分析是‎因为内存太小‎,而我的程序所‎用内存又正好‎卡在JVM所‎开内存边上,不至于溢出.当程序运行时‎就得花费大部‎分时间去调用‎GC去,这样就导致了‎为什么相同的‎循环出现两种‎不同的效率~!顺便把内存使‎用情况的方法‎也贴出来:public‎static‎String‎getMem‎U sage() {long free = ng.Runtim‎e.getRun‎t ime().freeMe‎m ory();long total = ng.Runtim‎e.getRun‎t ime().totalM‎e mory();String‎B uffer‎buf = new String‎B uffer‎();buf.append‎("[Mem: used ").append‎((total-free)>>20).append‎("M free ").append‎(free>>20).append‎("M total ").append‎(total>>20).append‎("M]");return‎buf.toStri‎n g();}google‎一下,大概就说JV‎M是这样来操‎作内存:堆(Heap)和非堆(Non-heap)内存按照官方的说法‎:"Java 虚拟机具有一‎个堆,堆是运行时数‎据区域,所有类实例和‎数组的内存均‎从此处分配.堆是在 Java 虚拟机启动时‎创建的.""在JVM中堆‎之外的内存称‎为非堆内存(Non-heap memory‎)".可以看出JV‎M主要管理两‎种类型的内存‎:堆和非堆.简单来说堆就‎是Java代‎码可及的内存‎,是留给开发人‎员使用的;非堆就是JV‎M留给自己用的,所以方法区,JVM内部处‎理或优化所需‎的内存(如JIT编译‎后的代码缓存‎),每个类结构(如运行时常数‎池,字段和方法数‎据)以及方法和构‎造方法的代码都在非‎堆内存中.堆内存分配JVM初始分‎配的内存由-Xms指定,默认是物理内‎存的1/64;JVM最大分‎配的内存由-Xmx指定,默认是物理内‎存的1/4.默认空余堆内‎存小于40%时,JVM就会增‎大堆直到-Xmx的最大‎限制;空余堆内存大‎于70%时, JVM会减少‎堆直到-Xms的最小‎限制.因此服务器一‎般设置-Xms,-Xmx相等以‎避免在每次G‎C后调整堆的大‎小.非堆内存分配‎JVM使用-XX:PermSi‎z e设置非堆‎内存初始值,默认是物理内‎存的1/64;由XX:MaxPer‎m Size设‎置最大非堆内‎存的大小,默认是物理内‎存的1/4.JVM内存限‎制(最大值)首先JVM内存‎首先受限于实‎际的最大物理‎内存,假设物理内存‎无限大的话,JVM 内存的‎最大值跟操作‎系统有很大的‎关系.简单的说就3‎2位处理器虽‎然可控内存空‎间有4GB,但是具体的操‎作系统会给一‎个限制,这个限制一般‎是 2GB-3GB(一般来说Wi‎n dows系‎统下为1.5G-2G,Linux系‎统下为2G-3G),而64bit‎以上的处理器‎就不会有限制‎了JVM内存的‎调优1. Heap设定‎与垃圾回收J‎a va Heap分为‎3个区,Young,Old和Pe‎r manen‎t.Young 保‎存刚实例化的‎对象.当该区被填满‎时,GC会将对象‎移到Old 区.Perman‎e nt区则负‎责保存反射对‎象,本文不讨论该‎区.JVM的He‎a p分配可以‎使用-X参数设定,-Xms初始Heap‎大小-Xmxjava heap最大‎值-Xmnyoung genera‎t ion的h‎e ap大小JVM有2个‎G C线程.第一个线程负‎责回收Hea‎p的Youn‎g区.第二个线程在‎H eap不足‎时,遍历Heap‎,将Young‎区升级为Ol‎d er区.Older区‎的大小等于-Xmx减去-Xmn,不能将-Xms的值设‎的过大,因为第二个线‎程被迫运行会‎降低JVM的‎性能.为什么一些程‎序频繁发生G‎C?有如下原因:l 程序内调用了‎S ystem‎.gc()或Runti‎m e.gc().l 一些中间件软‎件调用自己的‎G C方法,此时需要设置‎参数禁止这些‎G C.l Java的H‎e ap太小,一般默认的H‎e ap值都很‎小.l 频繁实例化对‎象,Releas‎e对象.此时尽量保存‎并重用对象,例如使用St‎r ingBu‎f fer()和Strin‎g().如果你发现每‎次GC后,Heap的剩‎余空间会是总‎空间的50%,这表示你的H‎e ap处于健‎康状态.许多Serv‎e r端的Ja‎v a程序每次‎G C后最好能‎有65%的剩余空间.经验之谈:1.Server‎端JVM最好‎将-Xms和-Xmx设为相‎同值.为了优化GC‎,最好让-Xmn值约等‎于-Xmx的1/3[2].2.一个GUI程‎序最好是每1‎0到20秒间‎运行一次GC‎,每次在半秒之‎内完成[2]. 注意:1.增加Heap‎的大小虽然会‎降低GC的频‎率,但也增加了每‎次GC的时间‎.并且GC运行‎时,所有的用户线‎程将暂停,也就是GC期‎间,Java应用‎程序不做任何‎工作. 2.Heap大小‎并不决定进程‎的内存使用量‎.进程的内存使‎用量要大于-Xmx定义的‎值,因为Java‎为其他任务分‎配内存,例如每个线程‎的Stack‎等.2.Stack的‎设定每个线程都有‎他自己的St‎a ck.-Xss每个线程的S‎t ack大小‎Stack的‎大小限制着线‎程的数量.如果Stac‎k过大就好导‎致内存溢漏.-Xss参数决‎定Stack‎大小,例如-Xss102‎4K.如果Stac‎k太小,也会导致St‎a ck溢漏.3.硬件环境硬件环境也影‎响GC的效率‎,例如机器的种‎类,内存,swap空间‎,和CPU的数‎量.如果你的程序‎需要频繁创建‎很多tran‎s ient对‎象,会导致JVM‎频繁GC.这种情况你可‎以增加机器的‎内存,来减少Swa‎p空间的使用‎[2].4.4种GC第一种为单线‎程GC,也是默认的G‎C.,该GC适用于‎单CPU机器‎.第二种为Th‎r oughp‎u t GC,是多线程的G‎C,适用于多CP‎U,使用大量线程‎的程序.第二种GC与‎第一种GC相‎似,不同在于GC‎在收集You‎n g区是多线‎程的,但在Old区‎和第一种一样‎,仍然采用单线‎程.-XX:+UsePar‎a llelG‎C参数启动该‎G C.第三种为Co‎n curre‎n t Low Pause GC,类似于第一种‎,适用于多CP‎U,并要求缩短因‎G C造成程序‎停滞的时间.这种GC可以‎在Old区的‎回收同时,运行应用程序‎.-XX:+UseCon‎c MarkS‎w eepGC‎参数启动该G‎C.第四种为In‎c remen‎t al Low Pause GC,适用于要求缩‎短因GC造成‎程序停滞的时‎间.这种GC可以‎在Young‎区回收的同时‎,回收一部分O‎l d区对象.-Xincgc‎参数启动该G‎C.。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

JVM调优总结(一)-- 一些概念数据类型Java虚拟机中,数据类型可以分为两类:基本类型和引用类型。

基本类型的变量保存原始值,即:他代表的值就是数值本身;而引用类型的变量保存引用值。

―引用值‖代表了某个对象的引用,而不是对象本身,对象本身存放在这个引用值所表示的地址的位置。

基本类型包括:byte,short,int,long,char,float,double,Boolean,returnAddress引用类型包括:类类型,接口类型和数组。

堆与栈堆和栈是程序运行的关键,很有必要把他们的关系说清楚。

栈是运行时的单位,而堆是存储的单位。

栈解决程序的运行问题,即程序如何执行,或者说如何处理数据;堆解决的是数据存储的问题,即数据怎么放、放在哪儿。

在Java中一个线程就会相应有一个线程栈与之对应,这点很容易理解,因为不同的线程执行逻辑有所不同,因此需要一个独立的线程栈。

而堆则是所有线程共享的。

栈因为是运行单位,因此里面存储的信息都是跟当前线程(或程序)相关信息的。

包括局部变量、程序运行状态、方法返回值等等;而堆只负责存储对象信息。

为什么要把堆和栈区分出来呢?栈中不是也可以存储数据吗?第一,从软件设计的角度看,栈代表了处理逻辑,而堆代表了数据。

这样分开,使得处理逻辑更为清晰。

分而治之的思想。

这种隔离、模块化的思想在软件设计的方方面面都有体现。

第二,堆与栈的分离,使得堆中的内容可以被多个栈共享(也可以理解为多个线程访问同一个对象)。

这种共享的收益是很多的。

一方面这种共享提供了一种有效的数据交互方式(如:共享内存),另一方面,堆中的共享常量和缓存可以被所有栈访问,节省了空间。

第三,栈因为运行时的需要,比如保存系统运行的上下文,需要进行地址段的划分。

由于栈只能向上增长,因此就会限制住栈存储内容的能力。

而堆不同,堆中的对象是可以根据需要动态增长的,因此栈和堆的拆分,使得动态增长成为可能,相应栈中只需记录堆中的一个地址即可。

第四,面向对象就是堆和栈的完美结合。

其实,面向对象方式的程序与以前结构化的程序在执行上没有任何区别。

但是,面向对象的引入,使得对待问题的思考方式发生了改变,而更接近于自然方式的思考。

当我们把对象拆开,你会发现,对象的属性其实就是数据,存放在堆中;而对象的行为(方法),就是运行逻辑,放在栈中。

我们在编写对象的时候,其实即编写了数据结构,也编写的处理数据的逻辑。

不得不承认,面向对象的设计,确实很美。

在Java中,Main函数就是栈的起始点,也是程序的起始点。

程序要运行总是有一个起点的。

同C语言一样,java中的Main就是那个起点。

无论什么java程序,找到main就找到了程序执行的入口:)堆中存什么?栈中存什么?堆中存的是对象。

栈中存的是基本数据类型和堆中对象的引用。

一个对象的大小是不可估计的,或者说是可以动态变化的,但是在栈中,一个对象只对应了一个4btye的引用(堆栈分离的好处:))。

为什么不把基本类型放堆中呢?因为其占用的空间一般是1~8个字节——需要空间比较少,而且因为是基本类型,所以不会出现动态增长的情况——长度固定,因此栈中存储就够了,如果把他存在堆中是没有什么意义的(还会浪费空间,后面说明)。

可以这么说,基本类型和对象的引用都是存放在栈中,而且都是几个字节的一个数,因此在程序运行时,他们的处理方式是统一的。

但是基本类型、对象引用和对象本身就有所区别了,因为一个是栈中的数据一个是堆中的数据。

最常见的一个问题就是,Java中参数传递时的问题。

Java中的参数传递时传值呢?还是传引用?要说明这个问题,先要明确两点:1. 不要试图与C进行类比,Java中没有指针的概念2. 程序运行永远都是在栈中进行的,因而参数传递时,只存在传递基本类型和对象引用的问题。

不会直接传对象本身。

明确以上两点后。

Java在方法调用传递参数时,因为没有指针,所以它都是进行传值调用(这点可以参考C的传值调用)。

因此,很多书里面都说Java是进行传值调用,这点没有问题,而且也简化的C中复杂性。

但是传引用的错觉是如何造成的呢?在运行栈中,基本类型和引用的处理是一样的,都是传值,所以,如果是传引用的方法调用,也同时可以理解为―传引用值‖的传值调用,即引用的处理跟基本类型是完全一样的。

但是当进入被调用方法时,被传递的这个引用的值,被程序解释(或者查找)到堆中的对象,这个时候才对应到真正的对象。

如果此时进行修改,修改的是引用对应的对象,而不是引用本身,即:修改的是堆中的数据。

所以这个修改是可以保持的了。

对象,从某种意义上说,是由基本类型组成的。

可以把一个对象看作为一棵树,对象的属性如果还是对象,则还是一颗树(即非叶子节点),基本类型则为树的叶子节点。

程序参数传递时,被传递的值本身都是不能进行修改的,但是,如果这个值是一个非叶子节点(即一个对象引用),则可以修改这个节点下面的所有内容。

堆和栈中,栈是程序运行最根本的东西。

程序运行可以没有堆,但是不能没有栈。

而堆是为栈进行数据存储服务,说白了堆就是一块共享的内存。

不过,正是因为堆和栈的分离的思想,才使得Java的垃圾回收成为可能。

Java中,栈的大小通过-Xss来设置,当栈中存储数据比较多时,需要适当调大这个值,否则会出现ng.StackOverflowError异常。

常见的出现这个异常的是无法返回的递归,因为此时栈中保存的信息都是方法返回的记录点。

JVM调优总结(二)-一些概念Java对象的大小基本数据的类型的大小是固定的,这里就不多说了。

对于非基本类型的Java对象,其大小就值得商榷。

在Java中,一个空Object对象的大小是8byte,这个大小只是保存堆中一个没有任何属性的对象的大小。

看下面语句:这样在程序中完成了一个Java对象的生命,但是它所占的空间为:4byte+8byte。

4byte 是上面部分所说的Java栈中保存引用的所需要的空间。

而那8byte则是Java堆中对象的信息。

因为所有的Java非基本类型的对象都需要默认继承Object对象,因此不论什么样的Java对象,其大小都必须是大于8byte。

有了Object对象的大小,我们就可以计算其他对象的大小了。

其大小为:空对象大小(8byte)+int大小(4byte)+Boolean大小(1byte)+空Object引用的大小(4byte)=17byte。

但是因为Java在对对象内存分配时都是以8的整数倍来分,因此大于17byte的最接近8的整数倍的是24,因此此对象的大小为24byte。

这里需要注意一下基本类型的包装类型的大小。

因为这种包装类型已经成为对象了,因此需要把他们作为对象来看待。

包装类型的大小至少是12byte(声明一个空Object至少需要的空间),而且12byte没有包含任何有效信息,同时,因为Java对象大小是8的整数倍,因此一个基本类型包装类的大小至少是16byte。

这个内存占用是很恐怖的,它是使用基本类型的N倍(N>2),有些类型的内存占用更是夸张(随便想下就知道了)。

因此,可能的话应尽量少使用包装类。

在JDK5.0以后,因为加入了自动类型装换,因此,Java虚拟机会在存储方面进行相应的优化。

引用类型对象引用类型分为强引用、软引用、弱引用和虚引用。

强引用:就是我们一般声明对象是时虚拟机生成的引用,强引用环境下,垃圾回收时需要严格判断当前对象是否被强引用,如果被强引用,则不会被垃圾回收软引用:软引用一般被做为缓存来使用。

与强引用的区别是,软引用在垃圾回收时,虚拟机会根据当前系统的剩余内存来决定是否对软引用进行回收。

如果剩余内存比较紧张,则虚拟机会回收软引用所引用的空间;如果剩余内存相对富裕,则不会进行回收。

换句话说,虚拟机在发生OutOfMemory时,肯定是没有软引用存在的。

弱引用:弱引用与软引用类似,都是作为缓存来使用。

但与软引用不同,弱引用在进行垃圾回收时,是一定会被回收掉的,因此其生命周期只存在于一个垃圾回收周期内。

强引用不用说,我们系统一般在使用时都是用的强引用。

而―软引用‖和―弱引用‖比较少见。

他们一般被作为缓存使用,而且一般是在内存大小比较受限的情况下做为缓存。

因为如果内存足够大的话,可以直接使用强引用作为缓存即可,同时可控性更高。

因而,他们常见的是被使用在桌面应用系统的缓存。

JVM调优总结(三)-基本垃圾回收算法可以从不同的的角度去划分垃圾回收算法:按照基本回收策略分引用计数(Reference Counting):比较古老的回收算法。

原理是此对象有一个引用,即增加一个计数,删除一个引用则减少一个计数。

垃圾回收时,只用收集计数为0的对象。

此算法最致命的是无法处理循环引用的问题。

标记-清除(Mark-Sweep):此算法执行分两阶段。

第一阶段从引用根节点开始标记所有被引用的对象,第二阶段遍历整个堆,把未标记的对象清除。

此算法需要暂停整个应用,同时,会产生内存碎片。

复制(Copying):此算法把内存空间划为两个相等的区域,每次只使用其中一个区域。

垃圾回收时,遍历当前使用区域,把正在使用中的对象复制到另外一个区域中。

次算法每次只处理正在使用中的对象,因此复制成本比较小,同时复制过去以后还能进行相应的内存整理,不会出现―碎片‖问题。

当然,此算法的缺点也是很明显的,就是需要两倍内存空间。

标记-整理(Mark-Compact):此算法结合了―标记-清除‖和―复制‖两个算法的优点。

也是分两阶段,第一阶段从根节点开始标记所有被引用对象,第二阶段遍历整个堆,把清除未标记对象并且把存活对象―压缩‖到堆的其中一块,按顺序排放。

此算法避免了―标记-清除‖的碎片问题,同时也避免了―复制‖算法的空间问题。

按分区对待的方式分增量收集(Incremental Collecting):实时垃圾回收算法,即:在应用进行的同时进行垃圾回收。

不知道什么原因JDK5.0中的收集器没有使用这种算法的。

分代收集(Generational Collecting):基于对对象生命周期分析后得出的垃圾回收算法。

把对象分为年青代、年老代、持久代,对不同生命周期的对象使用不同的算法(上述方式中的一个)进行回收。

现在的垃圾回收器(从J2SE1.2开始)都是使用此算法的。

按系统线程分串行收集:串行收集使用单线程处理所有垃圾回收工作,因为无需多线程交互,实现容易,而且效率比较高。

但是,其局限性也比较明显,即无法使用多处理器的优势,所以此收集适合单处理器机器。

当然,此收集器也可以用在小数据量(100M左右)情况下的多处理器机器上。

并行收集:并行收集使用多线程处理垃圾回收工作,因而速度快,效率高。

而且理论上CPU 数目越多,越能体现出并行收集器的优势。

并发收集:相对于串行收集和并行收集而言,前面两个在进行垃圾回收工作时,需要暂停整个运行环境,而只有垃圾回收程序在运行,因此,系统在垃圾回收时会有明显的暂停,而且暂停时间会因为堆越大而越长。

相关文档
最新文档