jvm原理及性能调优 jvm运行原理及性能调优

2025-04-14 01:30 - 立有生活网

JVM 参数怎么调

基于 JVM 的语言和应用程序汗牛充栋,不仅限于 Ja , 还有 Scala , JPython, JRuby。对于 JVM 的调优是每个JVM 应用开发者必需要了解的。

jvm原理及性能调优 jvm运行原理及性能调优jvm原理及性能调优 jvm运行原理及性能调优


jvm原理及性能调优 jvm运行原理及性能调优


jvm原理及性能调优 jvm运行原理及性能调优


先回顾一下 JVM 的结构

堆内部的分代

JVM 参数既多且杂,如何提纲挈领,避免挂一漏万呢?个人的想法是掌握原理,了解常用的参数就好了,以度量来驱动适用于你的应用程序的参数设置。

目的: 尽量减少停顿时间,释放出更多可用内存

Ja 命令行选项一般分为三类

以 Cassandra 为例,它是的一个高性能的分布式NOSQL 数据存储系统,它设置了如下 JVM 参数:

一般来说,比较常用的方法是通过 JMX 和 GC log 来度量你的 JVM 参数设置是是否合理,一旦发现异常或者 OOM 要马上采取措施进行调整

关于 JVM 内存溢出的分析可以参考以前写的 内存溢出不可怕,手足无措才尴尬

JVM性能调优(2) —— 内存设置和查看GC日志

1)JVM内存分配有如下一些参数:

一般 -Xms 和 -Xmx 设置一样的大小,-XX:MetaspaceSize 和 -XX:MaxMetaspaceSize 设置一样的大小。-Xms 等价于 -XX:InitialHeapSize,-Xmx等价于-XX:MaxHeapSize;-Xmn等价于-XX:MaxNewSize。

2)在IDEA中可以按照如下方式设置JVM参数:

3)命令行启动时可以按照如下格式设置:

1)设置GC参数:

可以在启动时加上如下参数来查看GC日志:

例如,我在IDEA中添加了如下JVM启动参数:

启动程序之后打印出了如下的一些日志:

从第三行 CommandLine flags 可以得到如下的信息:

2)查看默认参数:

如果要查看JVM的默认参数,就可以通过给JVM加打印GC日志的参数,就可以在GC日志中看到JVM的默认参数了。

还可以在启动参数中添加 -XX:+PrintFlagsFinal 参数,将会打印系统的所有参数,就可以看到自己配置的参数或系统的默认参数了:

3)GC日志:

之后的日志就是每次回收时产生的日志,每行日志说明了这次GC的执行情况,例如第四行GC日志:

详细内容如下:

2020-09-25T13:00:41.631+0800:GC发生的时间点。

4.013:系统运行多久之后发生的GC,单位秒,这里就是系统运行 4.013 秒后发生了一次GC。

GC (Allocation Failure):说明了触发GC的原因,这里是指对象分配失败导致的GC。

PSYoungGen:指触发的是年轻代的回收,使用的是 Parallel Scenge 回收器。

419840K->20541K:对年轻代执行了一次GC,GC之前年轻代使用了 419840K,GC之后有 20541K 的对象活下来了。

(472064K):年轻代可用空间是 472064K,即 461 M,为什么是461M呢?因为新生代大小为 512M,Eden 区占 409.6M,两块 Survivor 区各占 51.2M,所以年轻代的可用空间为 Eden+1个Survivor的大小,即460.8M,约为461M。

419840K->20573K:GC前整个堆内存使用了 419840K,GC之后堆内存使用了 20573K。

(996352K):整个堆的大小是 996352K,即 973M,其实就是年轻代的 461M + 老年代的 512 M

0.0118345 secs:本次GC耗费的时间

Times: user=0.00 sys=0.00, real=0.01 secs:本次GC耗费的时间

4)JVM退出时的GC情况:

程序结束运行后,还会打印一些日志,就是第12行之后的日志,这部分展示的是当前堆内存的使用情况:

详细内容如下:

jvm调优如何做?

Jvm调优依次参考如下

如果没有必要,请不要做调优

如果没有必要,请不要做调优。没有的调优,只有根据使用场景选择合适的手段,初始默认指定堆大小,元空间大小(jdk8)即可

确认性能问题由JVM再考虑调优,如fullGC频繁,GC时间较长,内存使用不正常,OOM等。开启JVM,记录GC日志,分析GC情况

JVM调优的目标是减少/避免老年代GC

对于追求响应时间的如web系统使用并发回收器(jdk8开启G1,低版本使用CMS)

根据JVM内存使用情况,可以考虑手动设置年轻代大小,survivor区大小,减少/避免进入老年代(注意jdk8默认开启自适应调节,需关闭)

影响GC时间的还有GC线程数等等,需要结合GC日志分析GC过程可能存在的问题

jvm性能调优都做了什么

JVM性能调优有很多设置,这个参考JVM参数即可.

主要调优的目的:

控制GC的行为.GC是一个后台处理,但是它也是会消耗系统性能的,因此经常会根据系统运行的程序的特性来更改GC行为

控制JVM堆栈大小.一般来说,JVM在内存分配上不需要你修改,(举例)但是当你的程序新生代对象在某个时间段产生的比较多的时候,就需要控制新生代的堆大小.同时,还要需要控制总的JVM大小避免内存溢出

控制JVM线程的内存分配.如果是多线程程序,产生线程和线程运行所消耗的内存也是可以控制的,需要通过一定时间的观测后,配置结果

JVM调优常用参数配置

说明:

1、一般初始堆和堆设置一样,因为:现在内存不是什么稀缺的资源,但是如果不一样,从初始堆到堆的过程会有一定的性能开销,所以一般设置为初始堆和堆一样。64位系统理论上可以设置为无限大,但是一般设置为 4G ,因为如果再大,JVM进行回收出现的暂停时间会比较长,这样全GC过长,影响JVM对外提供服务,所以不能太大。一般设置为4G。

2、-XX:NewRaio和-XX:SurvivorRatio这两个参数,都是设置年轻代和年老代的大小的,设置一个即可,是设置年轻代的大小,第二个是设置比值,理论上设置一个既可以满足需求

打印GC回收的过程日志信息

以下配置主要针对分代收集回收算法而言

年轻代的设置很关键

JVM中堆大小有三方面限制:相关作系统的数据模型(32bit还是64bit)限制:系统的可用虚拟内存限制;系统的可用物理内存限制。32位系统下,一般限制在1.5G-2G;64位作系统对内存没有限制。在Windows 2003系统,3.5G物理内存,JDK5.0下测试,设置为1478m。

典型设置:

JVM给了三种选择:串行收集器,并行收集器,并发收集器,但是串行收集器只适用于小数据量的情况,一般不考虑使用了,所以这里只针对并行收集器和并发收集器。默认情况下,JDK5.0以前是使用的串行收集器,如果想使用其他收集器需要在启动时加入相应的参数, JDK5.0以后,JVM会根据系统当前的配置进行判断

吞吐量优先的并行收集器

并行收集器主要以到达一定的吞吐量为目标,适用于后台处理

响应时间优先的并发收集器

并发收集器主要是保证系统的响应时间,减少收集时的停顿时间。适用于应用、电信领域等。

6.1年轻代大小选择

响应时间优先的应用:尽可能设置大,直到接近系统的响应时间限制(根据实际情况选择)。在此种情况下,年轻代收集发生的频率也是小的。同时减少到达年老代的对象。

吞吐量优先的应用:尽可能的设置大,可能到达Gbit的成都,因为对响应时间没有要求,收集可以并行进行,一般适合8核CPU以上应用。

6.2年老代大小选择

响应时间优先的应用:年老代使用并发收集器,所以其大小需要小心设置,一般要考虑并发会话率和会话持续时间等一些参数。如果堆设置小了,可能会造成内存碎片、高回收频率以及应用暂停而使用传统的标记清除方式;如果堆大了,则需要较长的收集时间。化的方案,一般需要参考一下数据获得:

1、并发收集信息

2、持久代并发收集次数

3、传统GC信息

4、花在年轻代和年老代回收上的时间比例减少年轻代和年老代花费的时间,一般会提高应用的效率

6.3吞吐量优先的应用

一般吞吐量优先的应用都有一个很大的年轻代和一个较小的年老代。原因是,这样可以尽可能回收掉大部分短期对象,减少中期对象,而年老代尽存放长期存活的对象

6.4较小堆引起的碎片问题

因为年老代的并发收集器使用标记、清除算法,所以不会对堆进行压缩。当收集器回收时,他会把相邻的空间进行合并,这样可以分配给较大的对象。但是当堆空间较小时,运行一段时间以后,就会出现“碎片”,如果并发收集器找不到足够的空间,那么并发收集器将会停止,然后使用传统的标记、清除方式进行回收。如果出现“碎片”,可能需要进行如下配置:

Jconsole,jProfile,VisualVM

Jconsole:jdk自带, 功能简单,但是可以再系统有一定负荷的情况下使用,对回收算法有很详细的跟踪。

JProfiler:商业软件,需要付费,但是功能强大

VisualVM:JDK自带,功能强大,与Jprofiler类似,

观察内存释放情况、类检查,对象树

上面这些调优工具都提供了强大的功能,但是总的来说一般分为以下几类功能:

一般就是根据回收前后情况对比,同时根据对象引用情况( 常见的对象引用 )分析,基本都可以找到泄漏点。

持久代沾满处理:

1、-XX:MaxPermSize=16m

2、换JDK比如:JRocket

系统内存被沾满:

一般是因为没有足够的资源产生线程造成的,系统创建线程时,除了要在Ja堆中分配内存外,作系统本身也需要分配资源来创建线程。因此,当线程数量大的一定程度以后,堆中或许还有空间,但是作系统分配不出资源来了,出现异常。

分配给Ja虚拟机的内存越多,系统剩余的资源就越少,因此,当系统内存固定时,分配给Ja虚拟机的内存越多,那么,系统总共能够产生的线程也就越少,两者成反比。同事,可以通过修改-Xss来减少分配给单个线程的空间,也可以增加系统总共生产的线程数。

ja程序内存问题的诊断方法:

查看jmap的命令参数,帮助查看堆信息

2023高考结束时间是几号_2023年高考时间是几号

2023年浙江省高考时间表 一般每年高考时间相同。高考是每个学生人生中非常重要的一次考试,它关系到你未来的发展和梦想的实现。在备考期间,需要提前制定好合理的学习,有条不紊地进行备考···

淘宝话术大全 淘宝话术大全短句合集

淘宝卖家好评回复语大全通用50条 二、当回复了买家的问题,请把光标移到非文字录入区。 网上购物渐渐成为人们的一种习惯,当我们在网上购物收到物品之后,一般会对这个商品进行好评,稍后···

黄石市中考分数查询 黄石市中考分数查询入口

源源给大家谈谈黄石市中考分数查询,以及黄石市中考分数查询入口应用的知识点,希望对你所遇到的问题有所帮助。 黄石市中考分数查询 黄石市中考分数查询入口 黄石市中考分数查询 黄石市中···