当前位置: 首页 > 科技观察

一个性能更好的JVM参数配置

时间:2023-03-18 13:56:05 科技观察

一个性能更好的webserverjvm参数配置:-server//服务器模式-Xmx2g//JVM***允许分配堆内存,按需分配-Xms2g//JVM初始分配堆内存一般配置和Xmx一样,避免每次gc后JVM重新分配内存。-Xmn256m//新生代内存大小,整个JVM内存=新生代+老年代+持久代-XX:PermSize=128m//永久代内存大小-Xss256k//设置每个线程的栈大小-XX:+DisableExplicitGC//忽略手动GC调用,System.gc()的调用会变成空调,根本不会触发GCPause-XX:+UseCMSCompactAtFullCollection//FULLGC时老年代的压缩-XX:LargePageSizeInBytes=128m//内存页的大小-XX:+UseFastAccessorMethods//原始类型的快速优化-XX:+UseCMSInitiatingOccupancyOnly//使用手动定义初始化和定义启动CMS收集-XX:CMSInitiatingOccupancyFraction=70//使用cms作为垃圾回收,70%使用率后开始CMS回收说明:-Xmn和-Xmx的比例大约是1:9,如果新生代内存设置太大的话,young需要很长时间GC。一个好的web系统应该能够在每次请求http请求时在younggc中回收内存,而fullgc永远不会发生。当然,这是最理想的情况。xmn的值要保证足够(Enoughforhttpconcurrentrequests),在web服务器和游戏服务器的配置思路不一样的前提下,尽量设置的小一些。最主要的区别就是游戏服务器的xmn,也就是新生代设置的比较大,Xmx大约是1:3因为游戏服务器一般都是长连接,所以之后需要更大的新生代堆内存保持一定的并发量。如果size设置的太大,往往会导致younggc引入JVM。从上图我们可以看出JVM堆内存的分类情况,JVM内存被分成了独立的部分。从广义上讲,JVM堆内存分为两部分——新生代和老年代。年轻一代年轻一代是创建所有新对象的地方。当新生代内存空间耗尽时,就会触发垃圾回收。这种垃圾回收称为MinorGC。新生代分为3个部分——Enden区和两个Survivor区。新生代空间要点:大多数新创建的对象位于伊甸区。当Eden区被对象填满时,就会执行MinorGC。并将所有幸存的物体转移到其中一个幸存者区域。MinorGC也会检查存活的对象,将它们转移到另一个存活区。这样一来,幸存者区总会有一段时间是空的。经过多次GC循环后,存活下??来的对象会被转移到老年代内存空间。通常这是通过在年轻一代有资格提升到老一代之前设置一个年龄阈值来完成的。老年代老年代的内存包含了长寿命的对象和在多次MinorGC中幸存下来的对象。垃圾收集通常在老年代已满时执行。老年代垃圾回收称为MajorGC。MajorGC会花费更多的时间。StoptheWorld事件所有垃圾回收都是“StoptheWorld”事件,因为在操作完成之前所有应用程序线程都会停止(因此得名“StoptheWorld”)。因为新生代中的对象都是临时的(短命的)对象,MinorGC的执行速度非常快,所以应用不会受到(“StoptheWorld”)的影响。由于MajorGC检查所有活动对象,因此需要更长的时间。应尽量减少主要GC。因为MajorGC会使您的应用程序在垃圾回收期间无响应,所以如果您的响应应用程序经历了多次MajorGC,您将看到超时错误。垃圾收集时间取决于垃圾收集策略。这就是为什么有必要监视和调整垃圾收集的原因。这避免了需要快速响应的应用程序中的超时错误。第一代第一代或“PermGen”包含JVM所需的应用程序元数据,用于描述应用程序中使用的类和方法。请注意,第一代不是Java堆内存的一部分。***代存放JVM运行时使用的类。第一代还包含JavaSE库的类和方法。第一代的对象在fullGC期间被垃圾收集。方法区方法区是生成空间的一部分,用来存放类型信息(运行时常量和静态变量)和方法代码和构造函数代码。内存池如果JVM实现了支持,JVM内存管理器会创建一个内存池,用于为不可变对象创建对象池。内存池类型的一个很好的例子是字符串池。一个内存池可以属于堆也可以属于第一代,这取决于JVM内存管理的实现。运行时常量池运行时常量池是每个类常量池的运行时表示。它包含类的运行时常量和静态方法。运行时常量池是方法区的一部分。Java堆栈内存Java堆栈内存用于运行线程。它们包含方法中的临时数据,堆中其他对象引用的特定数据。JavaGarbageCollectionJavaGarbageCollection查找未使用的对象,将它们从内存中删除,并为以后创建的对象释放内存。Java编程语言最大的优点之一就是自动垃圾回收,不像其他编程语言需要手动分配和释放内存,比如C语言。垃圾收集器是一个在后台运行的程序。它管理内存中的所有对象并查找未被引用的对象。所有这些未引用的对象都被删除,它们的空间被回收并分配给其他对象。基本的垃圾收集过程包括三个步骤:标记:这是第一步。在这一步中,垃圾收集器找出哪些对象正在使用,哪些对象没有。正常清理:垃圾收集器清理不再使用的对象并回收它们的空间以分配给其他对象。紧凑清理:为了提高性能,紧凑清理在删除未使用的对象后将所有幸存的对象一起移动。这提高了分配新对象的效率。简单的标记清除方法有两个问题:效率很低。因为大多数新创建的对象都会变成“无用对象”。通过多个垃圾收集周期的对象也有很好的机会在以后的周期中存活下来。上面这种简单的清除方式存在的问题是Java垃圾回收是分代回收的,堆内存中有两个区域:新生代和老年代。Java垃圾收集的类型应用程序中可以使用五种类型的垃圾收集。只需要使用JVM开关在我们的应用程序中启用垃圾收集策略。SerialGC(-XX:+UseSerialGC):SerialGC采用标记简单、清晰、紧凑的方式对新生代和老年代进行垃圾回收,即MinorGC和MajorGC。SerialGC在客户端模式(clientmode)下很有用,比如简单的单机应用程序和低CPU配置的机器。此模式对于占用较少内存的应用程序很有用。ParallelGC(-XX:+UseParallelGC):ParallelGC和SerialGC几乎一样,只是产生了N个线程用于新生代垃圾回收。这里的N是系统CPU的核心数。我们可以使用-XX:ParallelGCThreads=nJVM选项来控制线程数。并行垃圾收集器也称为吞吐量收集器。因为它使用多个CPU来加快垃圾收集性能。并行GC使用单线程进行老年代垃圾回收。ParallelOldGC(-XX:+UseParallelOldGC):同ParallelGC。不同的是,ParallelOldGC对新生代垃圾回收和老年代垃圾回收都采用多线程回收。ConcurrentMarkSweep(CMS)收集器(-XX:+UseConcMarkSweepGC):CMS收集器也称为短暂停并发收集器。它是在老年代收集的垃圾。CMS收集器通过多个线程并发进行垃圾收集,最大限度地减少垃圾收集造成的停顿。CMS收集器使用与并行收集器相同的年轻代垃圾收集算法。这种垃圾收集器适用于不能容忍长时间停顿并需要快速响应的应用程序。可以使用-XX:ParallelCMSThreads=nJVM选项限制CMS收集器的线程数。G1garbagecollector(-XX:+UseG1GC)G1(GarbageFirst):垃圾收集器是Java7之后才能使用的特性,其长期目标是取代CMS收集器。G1收集器是一个并行的、并发的、增量压缩的短暂停垃圾收集器。G1收集器与其他收集器的运作方式不同,不区分新生代和老年代空间。它将堆空间划分为大小相等的区域。在进行垃圾收集时,会优先收集存活对象较少的区域,因此称为“GarbageFirst”。