鍫嗘爤鍜屽爢鐨勫唴瀹瑰湪瀹氫綅闂鐨勬椂鍊欙紝閮芥槸闈炲父閲嶈鐨勪俊鎭傜嚎紼嬪爢鏍?dump 鍙互浜嗚В褰撴椂 JVM 涓墍鏈夌嚎紼嬬殑榪愯鎯呭喌錛屾瘮濡傜嚎紼嬬殑鐘舵佸拰褰撳墠姝e湪榪愯鐨勪唬鐮佽銆傚爢 dump 鍙互浜嗚В褰撴椂鍫嗙殑浣跨敤鎯呭喌錛屽悇涓被瀹炰緥鐨勬暟閲忓強鍚勪釜瀹炰緥鎵鍗犵敤鐨勭┖闂村ぇ灝忋?/p>
jstack 鏄?JDK 鑷甫鐨勫伐鍏鳳紝鐢ㄤ簬 dump 鎸囧畾榪涚▼ ID(PID)鐨?JVM 鐨勭嚎紼嬪爢鏍堜俊鎭?/p>
# 鎵撳嵃鍫嗘爤淇℃伅鍒版爣鍑嗚緭鍑?nbsp;jstack PID
# 鎵撳嵃鍫嗘爤淇℃伅鍒版爣鍑嗚緭鍑猴紝浼氭墦鍗板叧浜庨攣鐨勪俊鎭?nbsp;jstack -l PID
寮哄埗鎵撳嵃鍫嗘爤淇℃伅鍒版爣鍑嗚緭鍑猴紝濡傛灉浣跨敤 jstack PID 娌℃湁鍝嶅簲鐨勬儏鍐典笅(姝ゆ椂 JVM 榪涚▼鍙兘鎸傝搗)錛?br />鍔?nbsp;-F 鍙傛暟 jstack -F PID
jcmd 鏄?JDK 鑷甫鐨勫伐鍏鳳紝鐢ㄤ簬鍚?JVM 榪涚▼鍙戦佸懡浠わ紝鏍規嵁鍛戒護鐨勪笉鍚岋紝鍙互浠f浛鎴栭儴鍒嗕唬鏇?jstack銆乯map 絳夈傚彲浠ュ彂閫佸懡浠?nbsp;Thread.print
鏉ユ墦鍗板嚭 JVM 鐨勭嚎紼嬪爢鏍堜俊鎭?/p>
# 涓嬮潰鐨勫懡浠ゅ悓絳変簬 jstack PID
jcmd PID Thread.print
# 鍚岀瓑浜?nbsp;jstack -l PID
jcmd PID Thread.print -l
kill 鍙互鍚戠壒瀹氱殑榪涚▼鍙戦佷俊鍙?SIGNAL)錛岀己鐪佹儏鍐墊槸鍙戦佺粓姝?TERM) 鐨勪俊鍙?錛屽嵆 kill PID 涓?kill -15 PID 鎴?kill -TERM PID 鏄瓑浠風殑銆侸VM 榪涚▼浼氱洃鍚?QUIT 淇″彿(鍏跺間負 3)錛屽綋鏀跺埌榪欎釜淇″彿鏃訛紝浼氭墦鍗板嚭褰撴椂鐨勭嚎紼嬪爢鏍堝拰鍫嗗唴瀛樹嬌鐢ㄦ瑕侊紝鐩告瘮 jstack錛屾鏃跺浜嗗爢鍐呭瓨鐨勪嬌鐢ㄦ瑕佹儏鍐點備絾 jstack 鍙互鎸囧畾 -l 鍙傛暟錛屾墦鍗伴攣鐨勪俊鎭?/p>
kill -3 PID
# 鎴?nbsp;kill -QUIT PID
娣誨姞 JVM 鍙傛暟 -XX:+HeapDumpOnOutOfMemoryError 鍚庯紝褰撳彂鐢?OOM(OutOfMemory)鏃訛紝鑷姩鍫?dump銆傜己鐪佹儏鍐典笅錛孞VM 浼氬垱寤轟竴涓悕縐頒負 java_pidPID.hprof 鐨勫爢 dump 鏂囦歡鍦?JVM 鐨勫伐浣滅洰褰曚笅銆備絾鍙互浣跨敤鍙傛暟 -XX:HeapDumpPath=PATH 鏉ユ寚瀹?dump 鏂囦歡鐨勪繚瀛樹綅緗?/p>
# JVM 鍙戠敓 OOM 鏃訛紝浼氳嚜鍔ㄥ湪 /var/log/abc 鐩綍涓嬩駭鐢熷爢 dump 鏂囦歡 java_pidPID.hprof
java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/log/abc/
jmap 涔熸槸 JDK 鑷甫鐨勫伐鍏鳳紝涓昏鐢ㄤ簬鑾峰彇鍫嗙浉鍏崇殑淇℃伅銆?/p>
# 灝?nbsp;JVM 鐨勫爢 dump 鍒版寚瀹氭枃浠訛紝濡傛灉鍫嗕腑瀵硅薄杈冨錛岄渶瑕佺殑鏃墮棿浼氳緝闀匡紝瀛愬弬鏁?nbsp;format 鍙敮鎸?nbsp;b錛?br />鍗充簩榪涘埗鏍煎紡
jmap -dump:format=b,file=FILE_WITH_PATH
# 濡傛灉 JVM 榪涚▼鏈搷搴斿懡浠わ紝鍙互鍔犱笂鍙傛暟 -F 灝濊瘯
jmap -F -dump:format=b,file=FILE_WITH_PATH
# 鍙互鍙?nbsp;dump 鍫嗕腑鐨勫瓨媧誨璞★紝鍔犱笂 live 瀛愬弬鏁幫紝浣嗕嬌鐢?nbsp;-F 鏃朵笉鏀寔 live
jmap -dump:live,format=b,file=FILE_WITH_PATH
# -heap 鍙傛暟鐢ㄤ簬鏌ョ湅鎸囧畾 JVM 榪涚▼鐨勫爢鐨勪俊鎭紝鍖呮嫭鍫嗙殑鍚勪釜鍙傛暟鐨勫鹼紝鍫嗕腑鏂扮敓浠c佸勾鑰佷唬鐨勫唴瀛樺ぇ灝忋佷嬌鐢ㄧ巼絳?nbsp;
jmap -heap PID
# 鍚屾牱錛屽鏋?nbsp;JVM 榪涚▼鏈搷搴斿懡浠わ紝鍙互鍔犱笂鍙傛暟 -F 灝濊瘯
jmap -F -heap PID
涓涓疄渚嬭緭鍑哄涓嬶細
Attaching to process ID 68322, please wait
Debugger attached successfully.
Server compiler detected.
JVM version is 25.112-b16
using thread-local object allocation.
Parallel GC with 4 thread(s)
Heap Configuration:
MinHeapFreeRatio = 0
MaxHeapFreeRatio = 100
MaxHeapSize = 268435456 (256.0MB)
NewSize = 8388608 (8.0MB)
MaxNewSize = 89128960 (85.0MB)
OldSize = 16777216 (16.0MB)
NewRatio = 2
SurvivorRatio = 8
MetaspaceSize = 21807104 (20.796875MB)
CompressedClassSpaceSize = 1073741824 (1024.0MB)
MaxMetaspaceSize = 17592186044415 MB
G1HeapRegionSize = 0 (0.0MB)
Heap Usage:
PS Young Generation
Eden Space:
capacity = 41943040 (40.0MB)
used = 1701504 (1.6226806640625MB)
free = 40241536 (38.3773193359375MB)
4.05670166015625% used
From Space:
capacity = 4194304 (4.0MB)
used = 0 (0.0MB)
free = 4194304 (4.0MB)
0.0% used
To Space:
capacity = 5242880 (5.0MB)
used = 0 (0.0MB)
free = 5242880 (5.0MB)
0.0% used
PS Old Generation
capacity = 30408704 (29.0MB)
used = 12129856 (11.56793212890625MB)
free = 18278848 (17.43206787109375MB)
39.889421134159484% used
16658 interned Strings occupying 1428472 bytes.
鑾峰彇鍫嗕腑鐨勭被瀹炰緥緇熻
# 鎵撳嵃 JVM 鍫嗕腑鐨勭被瀹炰緥緇熻淇℃伅錛屼互鍗犵敤鍐呭瓨鐨勫ぇ灝忔帓搴忥紝鍚屾牱錛屽鏋?nbsp;JVM 鏈搷搴斿懡浠わ紝涔熷彲浠ヤ嬌鐢?nbsp;-F 鍙傛暟
jmap -histo PID
# 涔熷彲浠ュ彧緇熻鍫嗕腑鐨勫瓨媧誨璞★紝鍔犱笂 live 瀛愬弬鏁幫紝浣嗕嬌鐢?nbsp;-F 鏃朵笉鏀寔 live
jmap -histo:live PID
# 絳夊悓 jmap -dump:live,format=b,file=FILE_WITH_PATH
jcmd PID GC.heap_dump FILE_WITH_PATH
# 絳夊悓 jmap -dump:format=b,file=FILE_WITH_PATH
jcmd PID GC.heap_dump -all FILE_WITH_PATH
# 絳夊悓 jmap -histo:live PID
jcmd PID GC.class_histogram
# 絳夊悓 jmap -histo PID
jcmd PID GC.class_histogram -all
In this video I explain some 21 JVM parameters which are suited for most server applications. If you have any questions, you can read those links below for more information or just ask in the comments section.
I run several Java enterprise server applications. I often wondered – what are the best „default“ JVM settings for a server application to start with in production? I read a lot on the web and tried several things myself and wanted to share what I found out, so far. Links containing more information about JVM optimization can be found here:
http://blog.sokolenko.me/2014/11/javavm-options-production.html
http://www.petefreitag.com/articles/gctuning/
http://stas-blogspot.blogspot.de/2011/07/most-complete-list-of-xx-options-for.html
So let’s start:
-server
Use „-server“: All 64-bit JVMs use the server VM as default anyway. This setting generally optimizes the JVM for long running server applications instead of startup time. The JVM will collect more data about the Java byte code during program execution and generate the most efficient machine code via JIT.
-Xms=<heap size>[g|m|k] -Xmx=<heap size>[g|m|k]
The „-Xmx/-Xms“ settings specify the maximum and minimum values for the JVM heap memory. For servers, both params should have the same value to avoid heap resizing during runtime. I’ve applications running with 16GB heap sizes without an issue.
Depending on your application, you will have to try out how much memory will be best suited for your use case.
-XX:MaxMetaspaceSize=<metaspace size>[g|m|k]
Java 8 has no „Permanent Generation“ (PermGen) anymore but requires additional „Metaspace“ memory instead. This memory is used, in addition to the heap memory we specified before, for storing class meta data information.
The default size will be unlimited – I tend to limit MaxMetaspaceSize with a somewhat high value. Just in case something goes wrong with the application, the JVM will not hog all the memory of the server.
I suggest: Let your application run for a couple of days to get a feeling for how much Metaspace Size it uses normally. Upon next restart of the application set the limit to e.g. double the value.
-XX:+CMSClassUnloadingEnabled
Additionally, you might want to allow the JVM to unload classes which are held in memory but no code is pointing to them any more. If your application generates lots of dynamic classes, this is what you want.
-XX:+UseConcMarkSweepGC
This option makes the JVM use the ConcurrentMarkSweepGC – It can do much work in parallel to program execution but in some circumstances a „full GC“ with a „STW pause“ might still occur. I’ve read many articles and came to the conclusion that this GC is still the best one for server workloads.
-XX:+CMSParallelRemarkEnabled
The option CMSParallelRemarkEnabled means the remarking is done in parallel to program execution – which is what you want if your server has many cores (and most servers do).
-XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=<percent>
Normally the GC will use heuristics to know when it’s time to clear memory. GC might kick in too late with default settings (causing full-Gcs).
Some sources say it might be a good idea to disable heuristics altogether and just use generation occupancy to start a CMS collection cycle. Setting values around 70% worked fine for all of my applications and use cases.
-XX:+ScavengeBeforeFullGC
The first option tells the GC to first free memory by clearing out the „young generation“ or fairly new objects before doing a full GC.
-XX:+CMSScavengeBeforeRemark
CMSScavengeBeforeRemark does attempt a minor collection before the CMS remark phase – thus keeping the remark pause afterwards short.
-XX:+CMSClassUnloadingEnabled
The option „-XX:+CMSClassUnloadingEnabled“ here tells the JVM to unload classes, which are not needed any more by the running application. If you deploy war files to an application server like wildfly, tomcat or glassfish without restarting the server after the deployment, this flag is for you.
-XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses
The option „-XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses“ is especially important if your application uses RMI (remote method invocation). The usage of RMI will cause the JVM to do a FULL-GC EVERY HOUR! This might be a very bad idea for large heap sizes because the FULL-GC pause might take up to several seconds. It would be better to do a concurrent GC and try to unload unused classes to free up more memory – which is exactly what the second option does.
-XX:+PrintGCDateStamps -verbose:gc -XX:+PrintGCDetails -Xloggc:"<path to log>"
These options shown here will write out all GC related information to a specified log file. You can see how well your GC configuration works by looking into it.
I personally prefer to use the „Visual GC“ plug in for the „Visual VM“ tool to monitor the general JVM and GC behavior.
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=<path to dump>`date`.hprof
When your JVM runs out of memory, you will want to know why. Since the OOM error might be hard to reproduce and you want to get your production server up and running again – you should specify a path for a heap dump. When things have settled down, you can analyze the dump afterwards.
-Djava.rmi.server.hostname=<external IP> -Dcom.sun.management.jmxremote.port=<port>
These options will help you to specify an IP and port for JMX – you will need those ports open to connect remotely to a JVM running on a server for tools like VisualVM. You can gain deep insights over cpu and memory usage, gc behaviour, class loading, thread count and usage of your application this way.
Lastly, I would like to recommend to you the VisualVM tool which is bundled with the Java 8 JDK. You can use it to gain more insights about your specific application behaviour on the JVM – like cpu and memory usage, thread utilisation and much more.
VisualVM can be extended with a plug in called „Visual GC“. It will briefly show you VERY detailed information about the usage of the young and old generation object spaces. You can easily spot problems with garbage collection simply by analyzing these graphs during application runtime.
Thank you very much for watching! If you liked the video you might consider giving it a „thumbs up“. If you have any questions – just put them in the comments section. I will reply as quickly as possible.
-------------------------------------------------------
-XX:+UseCompressedOops [If Max Heap allocation is less than 32GB]
This can save a significant amount of memory and this option should already be enabled by default on recent java 8 versions. This option allowes object references to be stored as 32-bit values instead of 64-bit on 64-bit JVMs. This leads to before mentioned memory savings.
-XX:+AggressiveOpts
This option will enable performance options which are hoped to become enabled by default in upcoming released of the JVM. This option sets some performance settings but is marked as experimental! So you should only enable it, when you have to possibility to test your application thoroughly before enabling this flag on an production server.
-XX:+UseStringDeduplication
Since Java 8 update 20 you can use this option to reduce the memory usage of your application. The JVM will spot identical strings in memory, remove the duplicated and point all references to the remaining, single instance of the string.
-XX:+UseG1GC
Will tell the JVM to use the most recent G1 garbage collector. You are trading better application response times (due to shorter gc times with G1) against lower throughput (compared against good old ConcMarkSweepGC / CMS). If your application can deliver more value through short gc times, then G1 is definately better suited. Otherwise on Java 8, I’d recommend sticking with CMS.
Concerning your Tomcat 8 question, I’d suggest you have a look into it with the „VisualVM“ tool. Look at memory usage, GC times (visual GC plugin), pull and analyse stack traces or thread dumps to find the weak spot. You might also consider attaching a debugger to tomcat to find the bug.
https://www.maknesium.de/21-most-important-java-8-vm-options-for-servers
PermantSpace涓昏璐熻矗瀛樻斁鍔犺澆鐨?a style="color: #075db3;">Class綾葷駭瀵硅薄濡俢lass鏈韓錛?a style="color: #075db3;">method錛宖ield絳夊弽灝勫璞★紝涓鑸笉鐢ㄩ厤緗?/p>
JVM鐨凥eap鍖哄彲浠ラ氳繃-X鍙傛暟鏉ヨ瀹氥侶eapSpace= {Old + NEW {= Eden , from, to } }
褰撲竴涓猆RL琚闂椂錛屽唴瀛樼敵璇瘋繃紼嬪涓嬶細
Xms/Xmx錛氬畾涔塏EW+OLD孌電殑鎬誨昂瀵革紝ms涓篔VM鍚姩鏃禢EW+OLD鐨勫唴瀛樺ぇ灝忥紱mx涓烘渶澶у彲鍗犵敤鐨凬EW+OLD鍐呭瓨澶у皬銆傘傚湪鐢ㄦ埛鐢熶駭鐜涓婁竴鑸皢榪欎袱涓艱涓虹浉鍚岋紝浠ュ噺灝戣繍琛屾湡闂寸郴緇熷湪鍐呭瓨鐢寵涓婃墍鑺辯殑寮閿錛?nbsp;
NewSize/MaxNewSize錛氬畾涔夊崟鐙琋EW孌電殑灝哄錛孨ewSize涓篔VM鍚姩鏃禢EW鐨勫唴瀛樺ぇ灝忥紱MaxNewSize涓烘渶澶у彲鍗犵敤鐨凬EW鐨勫唴瀛樺ぇ灝忋傚湪鐢ㄦ埛鐢熶駭鐜涓婁竴鑸皢榪欎袱涓艱涓虹浉鍚岋紝浠ュ噺灝戣繍琛屾湡闂寸郴緇熷湪鍐呭瓨鐢寵涓婃墍鑺辯殑寮閿錛?/span>
Xms/Xmx鍜孨ewSize/MaxNewSize瀹氫箟濂藉悗錛孫LD鍖洪棿涔熻嚜鐒跺畾涔夊畬姣曚簡錛屽嵆OLD鍖哄垵濮嬪ぇ灝?錛圶ms-NewSize錛夛紝OLD鍖烘渶澶у彲鍗犵敤澶у皬=錛圶mx-MaxNewSize錛夛紱
PermSize/MaxPermSize錛氬畾涔塒erm孌電殑灝哄錛孭ermSize涓篔VM鍚姩鏃禤erm鐨勫唴瀛樺ぇ灝忥紱MaxPermSize涓烘渶澶у彲鍗犵敤鐨凱erm鍐呭瓨澶у皬銆傚湪鐢ㄦ埛鐢熶駭鐜涓婁竴鑸皢榪欎袱涓艱涓虹浉鍚岋紝浠ュ噺灝戣繍琛屾湡闂寸郴緇熷湪鍐呭瓨鐢寵涓婃墍鑺辯殑寮閿銆?/span>