关注分享主机优惠活动
国内外VPS云服务器

Jvm调优(jvm调优参数是什么)

摘要:内存调优的主要目的是减少频率和次数。调优工具主要用于输出在中运行的进程状态信息。调优工具总和用于查看堆内存使用情况,一般组合使用。

首先,jvm内存调优的主要目的是减少GC的频率和全GC的次数。

1.完全GC

整个堆将被排序,包括年轻,终身和烫发。全GC很慢,因为需要回收整个堆,所以要尽可能减少全GC的次数。排列

2.垃圾收集缓存满的原因

1)当老一代充满服务器调优时,尽可能让对象在新一代GC中回收,让对象在新一代中长时间存活,不要创建太大的对象和数组,避免直接在老一代中创建对象。并发性2)持久生成Pemanet生成空间不足。jvm增加Perm Gen空间,避免静态对象过多,控制新生代和老一代的高比例。3)显示System.gc()。调用工具垃圾回收,不要手动触发,尽可能依靠JVM自身的机制。

在调优JVM的过程中,很大一部分工作是调整FullGC。下面详细介绍了相应的JVM调优方法和步骤。

二、jvm性能调优工具和思路(重要)——面试必看2.1.JVM调优参数参考1。对于JVM堆设置,通常可以通过-Xms -Xmx来限制其最小值和最大值。为了防止垃圾收集器在最小值和最大值之间收缩堆,产生额外的时间,最大值和最小值一般设置为相同的值;2.年轻一代和老一代会按照默认的比例(1: 2)分配堆内存,可以通过调整他们之间的比例NewRadio来调整他们之间的大小,也可以用于回收代。和年轻一代一样,绝对大小设置为-XX:newSize -XX:MaxNewSize。同样,为了防止后辈堆收缩,我们通常会将-XX:newSize -XX:MaxNewSize设置为相同的大小。3.年轻一代和老一代的设定有多大?1)较大的年轻一代必然导致较小的老一代,较大的年轻一代会延长普通GC的周期,但会增加每次GC的时间;年轻一代会导致更频繁的全GC 2)年轻一代必然导致年长一代,年轻一代会导致频繁的一般GC,但每次GC时间会更短;老一代会减少全GC的频率。如何选择要看应用对象生命周期的分布:如果应用中有大量的临时对象,应该选择年轻一代;如果持久对象相对较多,则应适当增加老一代。但是许多应用程序没有这样明显的特征。选择要基于以下两点:(1)本着最小满GC的原则,尽可能让老一代缓存常用对象,JVM默认比例为1: 2。(2)观察应用一段时间后,看老一辈剩下的人在高峰期会占用多少内存。在不影响满GC的前提下,根据实际情况增加年轻一代,就像把比例控制在1: 1一样。但至少1/3的增长空间要留给老一辈。4.在配置好的机器上(比如多核大内存),可以选择老一代的并行收集算法:-xx: -XX:+UseParallelOldGC。5.线程栈设置:每个线程默认会打开一个1M的栈,用来存储栈帧、调用参数、局部变量等。对于大多数应用来说,这个默认值太高了,通常256K就足够了。理论上,在内存不变的情况下,减少每个线程的堆栈可以产生更多的线程,但这实际上是受到操作系统的限制。

2.2.调优工具的JPS (Java虚拟机进程状态工具)主要用于输出JVM中运行的进程状态信息。语法格式如下:

Jps [options] [hostid]如果不指定hostid,则默认为当前主机或服务器。命令行参数选项描述如下:

-q不输出传递给main方法的类名、Jar名和参数。-m输出传递给main方法的参数。-l输出主类或Jar的完全限定名。-v输出传递给JVM的参数。

例如以下内容:

root @ Ubuntu:/# jps -m -l 2458 org . artifactory . standalone . main . main/usr/local/artifactory -2 . 2 . 5/etc/jetty . XML 29920 com . sun . tools . hat . main -port 9998/tmp/dump . dat 3149 org . Apache . catalina . startup . bootstrap start 30972 sun . tools . jps . jps -m -l 8247 org . Apache . catalina语法格式如下:jstack[option]PID jstack[option]可执行核心jstack[option][server -id @]remote -hostname -or -IP命令行参数选项如下:-l长的清单,多余的锁信息会被打印出来。如果出现死锁,可以使用jstack -l pid观察锁持有情况。-m混合模式不仅会输出Java栈信息,还会输出C/C++栈信息(比如Native method)。

Jstack可以定位线程栈,我们可以根据栈信息定位具体的代码,所以在JVM性能调优中用的非常多。我们举个例子,找出一个Java进程中最消耗CPU的Java线程,定位堆栈信息。使用的命令有ps、top、printf、jstack和grep。

第一步是找出Java进程ID。我在服务器上部署的Java应用程序的名称是mrf-center:

root @ Ubuntu:/# PS -ef | grepmrf -center | grep -v grepmroot 21711114:47 pts/300:02:10 Java -jar Mr F-center . jar得到了21711的进程ID。第二步,找出进程中消耗CPU最多的线程。可以用ps -Lfp pid或者ps -mp pid -o线程,tid,time或者top -Hp pid。这里我用第三个,输出如下:

时间列是每个Java线程消耗的CPU时间。CPU时间最长的是线程ID为21742的线程,用

Printf "%x/n" 21742将21742的十六进制值作为54ee获取,这将在下面使用。

好了,接下来终于轮到jstack玩了,用来输出进程21711的堆栈信息,然后根据线程ID的十六进制值grep,如下:

root @ Ubuntu:/# jstack 21711 | grep 54ee " polltintervalryschedulerthread " prio = 10 tid = 0x 00007 f 950043 e 000 NID = 0x 54 ee在Object.wait()[0x 00007 f 94c 6 EDA 000]可以看到CPU是消耗在这个类PollindValretrySchedulerThread的object . wait()中。我查找我的代码,并将其定位到以下代码:

// Idle waitgetLog()。info("线程[" + getName() + "]正在空闲等待...");schedulerThreadState = PollTaskSchedulerThreadState。IdleWaitinglong now = system . current time millis();long wait time = now+getIdleWaitTime();long time until continue = wait time -now;synchronized(sigLock) { try { if(!halted . get()){ siglock . wait(timeUntilContinue);}} catch(中断异常忽略){}}它是轮询任务的空闲等待代码,上面的sigLock.wait(timeUntilContinue)对应的是前面的Object.wait()。

2.4.调优工具的jmap(内存映射)和jhat (Java堆分析工具)用于检查堆内存使用情况,一般与jhat结合使用。

Jmap语法格式如下:

JMAP [option] PID JMAP [option]可执行核心JMAP[option][server -id @]remote -hostname -or -IP如果在64位JVM上运行,您可能需要指定-J-d64命令选项参数。

Jmap -permstat pid打印类装入器和类装入器装入的持久生成对象信息,输出类装入器名称、对象是否存活(不可靠)、对象地址、父类装入器、装入的类大小等信息,如下图所示:

使用jmap -堆pid检查进程堆内存使用情况,包括GC算法、堆配置参数和每代堆内存使用情况。例如,下面的例子:

root @ Ubuntu:/# jmap -heap 21711正在连接到进程ID 21711,请稍候...调试器已成功附加。检测到服务器编译器。JVM版本是20.10-b01,使用thread -本地对象分配。具有4个线程的并行GC堆配置:minheafpreeratio = 40 MaxHeapFreeRatio = 70 MaxHeapSize = 2067791872(1972.0 MB)NewSize = 1310720(1.25 MB)MaxNewSize = 17592186044415 MB OldSize = 5439488(5.1875 MB)new ratio = 2 SurvivorRatio = 8 PermSize = 21757952 75.0%已用空间:容量= 131072 (0.125MB)已用空间= 0 (0.0MB)可用空间= 131072 (0.125MB) 0.0%已用空间旧一代容量= 35258368 (33.625MB)已用空间= 4119544 (3.9287033081054688MB)可用空间= 311138824(29.69662824 ...使用jmap -histo[:live] pid查看堆内存中对象的数量和大小的统计直方图,如果是live,则只计算live对象,如下所示:

root @ Ubuntu:/# jmap -histo:live 21711 | more num # instances # bytes class name -------------------------------------------------1:384419:2443 97720 Java . util . linked hashmap $ Entry 20:2072 82880 Java . lang . ref . soft reference 21:1807 71528[ljava . lang . object;22:2206 70592 Java . lang . ref . weak reference 23:934 52304 Java . util . linked hashmap 24:871 48776 Java . beans . method descriptor 25:1442 46144 Java . util . concurrent . concurrent hashmap $ hash entry 26:804 3859 2 Java . util . hashmap 27:948 37920 Java . util . concurrent hash29:1313 34880[ljava . lang . string;30:1396 33504 Java . util . linked list $ Entry 31:462 33264 Java . lang . reflect . field 32:1024 3 2768 Java . util . hashtable $ Entry 33:948 31440[ljava . util . concurrent . concurrent hashmap $ hash Entry;类名是一种对象类型,描述如下:

bbytec chard double float int j longz Boolean[array,如[I代表int[][L+ class name]其他对象有一种很常见的情况:用jmap把进程内存使用情况转储到一个文件中,然后用jhat进行分析。Jmap转储命令格式如下:

Jmap-Dump: format = b,file = dump文件名PID我用ID 21711转储上面的进程:

root @ Ubuntu:/# jmap -dump:format = b,file =/tmp/dump.dat21711将堆转储到/tmp/dump.dat...MAT、VisualVM等工具可以查看堆转储文件创建的转储。在这里,使用jhat查看:

root @ Ubuntu:/# jhat -port 9998/tmp/dump.dat从/tmp/dump . dat读取...转储文件创建于2014年1月28日星期二17:46:14 CST快照读取,解析...解析132207个对象...追踪参考文献,预计26点..........................消除重复引用..........................快照已解决。已启动端口9998上的HTTP服务器,服务器已准备就绪。注意,如果转储文件太大,可能需要添加参数-J-Xmx512m来指定最大堆内存,即jhat -J-xmx 512m -port 9998/tmp/Dump . dat..然后可以在浏览器中输入主机地址:9998。

你可以探索上面红线勾勒的部分,最后一个支持OQL (Object Query Language)。

2.5.jstat (JVM统计监控工具)的语法格式如下:

jstat[general option | output options vmid[interval[s | ms][count]]vmid是Java虚拟机id,在Linux/Unix系统上一般是进程id。Interval是采样间隔。计数是样本的数量。例如,以下输出是GC信息,采样时间间隔为250ms,采样数为4:

root @ Ubuntu:/# jstat -GC 21711 250 4 S0C S1C S0U S1U EC EU OC OU PC PU YGC YGCT FGC FGCT GCT 192.0 1 92.0 64.0 0.0 6144.0 1854.9 32000.0 4111.6 55296.0 25472.7 702 0.431 3 0.218 0.649192.0 192.0 1926 55296.0 25472.7 702 0.431 3 0.218 0.649192.0 192.0 64.0 0.0 6144.0 2109.7 32000.0 4111.6 55296.0 25472.7 702 0.431 3 0.218 0.649要理解以上各列的含义,首先要看JVM堆内存

可以看出:

堆内存=年轻一代+老一代+永久一代年轻一代=伊甸园区域+两个幸存者区域(From和To)

现在解释每列的含义:

S0C,S1C,S0U,s1u:残存0/1区域容量和已用)EC,EU: Eden区域容量和已用OC,OU:老一代容量和已用PC,PU:永久一代容量和已用YGC,YGT:年轻一代GC时间和GC耗时FGC,FGCT:完全GC时间和完全GC耗时GC。

2.6.HPROF(堆/CPU分析工具)HPROF可以显示CPU使用情况,并计算堆内存使用情况。

语法格式如下:

Java -agent lib:hprof[= options]tobeprofiled class Java -xrunprof[:options]tobeprofiled class javac -J-agent lib:hprof[= options]tobeprofiled class完整命令选项如下:

选项名称和值描述默认值----------------------------------------heap = dump | sites |所有堆分析allcpu = samples | times |旧cpu使用率offmonitor=y| n monitor争用nformat=a|b text(txt)或二进制输出txt] net=:通过套接字发送数据offdepth=堆栈跟踪深度4interval=以毫秒为单位的采样间隔10cutof f=输出截止点0.0001lineno=y|n跟踪中的行号?跟踪中的线程?ndoe=y|n退出时转储?ymsa = y | n Solaris microstate accounting nforce = y | n强制输出到yverbose = y | n打印有关转储的消息y来自几个官方指南的示例。

CPU使用率采样分析示例(CPU = samples):

Java -Agent Lib:hprof = CPU = samples,interval = 20,depth = 3 Hello每20毫秒采样一次CPU消耗信息,堆栈深度为3。生成的概要文件名称是java.hprof.txt,它位于当前目录中。

CPU使用率时间分析(CPU = Times)的一个例子是,它可以获得比CPU使用率采样分析更细粒度的CPU消耗信息,一直到每个方法调用的开始和结束,其实现使用字节码注入技术(BCI):

javac-J-agentlib示例:hprof = CPU = times Hello.java堆分配分析(heap = sites):

javac -J-agent lib:hprof = Heap = sites Hello.java堆转储(heap = dump)示例,它可以生成比上面的堆分配分析更详细的堆转储信息:

javac -J-代理库:hprof = Heap = dump Hello.java虽然在JVM启动参数中添加-Xrunprof:heap=sites可以生成CPU/Heap概要文件,但是对JVM性能影响很大,不建议用于在线服务器环境。

2.7.jconsole和JVM使用jconsole和JVM分析内存信息(Eden、Survivor、Old等各个区域的内存变化。).如果您查看远程服务器的JVM,您需要在启动程序时添加以下参数:

" -DCOM . sun . management . JMX remote = true " " -DJ ava . RMI . server . hostname = 12 . 34 . 56 . 78 " " -DCOM . sun . management . JMX remote . port = 18181 " " -DCOM . sun . management . JM x remote。authenticate = false ""-DCOM。sun . management . JMX remote . SSL = false "下图为jconsole界面,overview选项可用于观察堆内存使用情况、线程数量、类加载数量和CPU利用率;内存选项可以查看堆中每个区域的内存使用情况以及左下角的详细描述(内存大小、GC情况等。);Thread选项可以查看当前JVM加载的线程,查看每个线程的堆栈信息,检测死锁;虚拟机配置文件描述了虚拟机的各种详细参数。(jconsole函数演示)

下图是jvisualvm的界面,比jconsole略丰富,但大部分功能需要安装插件。概述类似于jconsole的VM概述,描述了jvm的详细参数和程序启动参数。监控显示类似于jconsole的概览界面(CPU、堆/方法区、类加载、线程);Thread和jconsole有类似的线程接口;采样器可以显示当前占用内存的类的排行榜和实例数;Visual GC可以更丰富的显示每个区域的当前内存占用大小和历史信息(下图)(jvisualvm函数演示)

工具路径://Java/JDK 1 . 8 XXX/bin/jvisuavm . exe。

监控本地Tomcat监控远程Tomcat监控公共JAVA进程。

不知道的可以看看这篇文章:如何使用JConsole观察分析Java程序的运行并调试调优?

2.8.Jinfo Jinfo命令主要用于查看应用程序的配置参数,打印运行JVM时指定的JVM参数。jinfo可以使用-sysprops选项打印出虚拟机进程中指定的System.getProperties()的内容,该命令还可以查看未显示的指定JVM参数的系统默认值,通过JPS -V无法看到,同时Jinfo命令还可以在运行时修改JVM参数,使用-flag name=value或-flag [+|-]name修改一些运行时可以修改的虚拟机参数。

其他工具如BTrace、Reference等。有兴趣的可以自己去查资料。

2.9.依赖和引用的数据包括用于调优的系统运行日志、堆栈错误信息、gc日志、线程快照和堆转储快照。这里参考大禹的文章:JVM性能调优也是一种思路。可以根据自己的业务场景或者其他因素进行筛选使用。

①系统运行日志:系统运行日志是打印在程序代码中的日志,在代码层面描述系统运行轨迹(执行方法、参数、返回值等。).在一般系统问题的情况下,系统运行日志是首先要检查的日志。

②堆栈错误消息:系统异常时,可以根据堆栈信息初步定位问题,比如根据“Java . lang . out memory error:Java heap space”,可以判断是堆内存溢出;根据“java.lang.StackOverflowError”可以判断是堆栈溢出;根据“Java . lang . out memory error:perm gen space”可以判断方法区溢出等等。③GC日志:程序启动

未经允许不得转载:主机频道 » Jvm调优(jvm调优参数是什么)

评论 抢沙发

评论前必须登录!