前言
給一個系統定位問題的時候,知識、經驗是關鍵基礎,數據是依據,工具是運用知識處理數據的手段。這里說的數據包括:運行日志、異常堆棧、GC日志、線程快照(threaddump/javacore文件)、堆轉儲快照(heapdump/hprof文件)等。經常使用適當的虛擬機監控和分析的工具可以加快我們分析數據、定位解決問題的速度。
目錄
一、jps:虛擬機進程狀況工具
二、jstat:虛擬機統計信息監視工具
三、jmap:Java內存印象工具
四、jhat:虛擬機堆轉儲快照分析工具
五、jstack:Java堆棧跟蹤工具
六、jinfo:Java配置信息工具
JDK的命令行工具
JDK的bin目錄下有很多用於監視虛擬機和故障處理的工具,這些工具都非常穩定而且功能強大,能在處理應用程序性能問題、定位故障是發揮很大的作用。比較細心的讀者可能會注意到這些工具的程序體積都異常小巧。並非JDK開發團隊刻意把它們制作得如此精煉來炫耀編程水平,而是因為這些命令行工具大多是jdk/lib/tools.jar類庫的一層薄包裝而已,它們主要的功能代碼是在tools類庫中實現的。
接下來介紹常用的一些工具。
一、jps:虛擬機進程狀況工具
JVM Process Status Tool,顯示指定系統內所有的HotSpot虛擬機進程。
命令格式:
jps [ options ] [ hostid ]
jps可以通過RMI協議查詢開啟了RMI服務的遠程虛擬機進程狀態,hostid為RMI注冊表中注冊的主機名。
jps工具主要選項:
選項 | 作用 |
-l | 輸出主類全名或jar路徑 |
-q | 只輸出LVMID |
-m | 輸出JVM啟動時傳遞給main()的參數 |
-v | 輸出JVM啟動時顯示指定的JVM參數 |
其中[ options ]、[ hostid ]參數也可以不寫。
示例:
$ ./jps -l -m 21332 org.tanukisoftware.wrapper.WrapperSimpleApp org.cellphone.gateway.WarehouseGateway 7516 kafka.Kafka config/server.properties 18140 sun.tools.jps.Jps -l -m
二、jstat:虛擬機統計信息監視工具
jstat(JVM statistics Monitoring)是用於監視虛擬機運行時狀態信息的命令,它可以顯示出虛擬機進程中的類裝載、內存、垃圾收集、JIT編譯等運行數據。
命令格式:
jstat [ option vmid [interval[s|ms] [count]] ]
對於命令格式中的VMID與LVMID需要特別說明一下:如果是本地虛擬機進程,VMID與LVMID是一致的,如果是遠程虛擬機進程,那VMID的格式應當是:
[protocol:][//]lvmid[@hostname[:port]/servername]
參數interval和count代表查詢間隔和次數,如果省略這兩個參數,說明只查詢一次。假設需要每250毫秒查詢一次進程2764垃圾收集狀況,一共查詢20次,那命令應當是:
jstat -gc 2764 250 20
選項option代表着用戶希望查詢的虛擬機信息,主要分為3類:類裝載、垃圾收集、運行期編譯狀況。
jstat工具主要選項:
選項 | 作用 |
-class | 監視類裝載、卸載數量、總空間以及類裝載所耗費的時間 |
-gc | 監視Java堆狀況,包括Eden區、兩個Survivor區、老年代、永久代等的容量、已用空間、GC時間合計等信息 |
-gccapacity | 監視內容與-gc基本相同,但輸出主要關注Java堆各個區域使用到的最大、最小空間 |
-gcutil | 監視內容與-gc基本相同,但輸出主要關注已使用空間占總空間的百分比 |
-gccause | 與 -gcutil 功能一樣,但是會額外輸出導致上一次GC產生的原因 |
-gcnew | 監視新生代GC狀況 |
-gcnewcapacity | 監視內容與 -gcnew 基本相同,輸出主要關注使用到的最大、最小空間 |
-gcold | 監視老年代GC狀況 |
-gcoldcapacity | 監視內容與 -gcold 基本相同,輸出主要關注使用到的最大、最小空間 |
-gcpermcapacity | 輸出永久代使用到的最大、最小空間 |
-compiler | 輸出JIT編譯器編譯過的方法、耗時等信息 |
-printcompilation | 輸出已經被JIT編譯的方法 |
option參數詳解
-class
監視類裝載、卸載數量、總空間以及耗費的時間。
$ ./jstat -class 21332 Loaded Bytes Unloaded Bytes Time 9263 16938.8 0 0.0 5.28
- Loaded : 加載class的數量
- Bytes : class字節大小
- Unloaded : 未加載class的數量
- Bytes : 未加載class的字節大小
- Time : 加載時間
-compiler
輸出JIT編譯過的方法數量耗時等。
$ ./jstat -compiler 21332 Compiled Failed Invalid Time FailedType FailedMethod 10998 2 0 84.47 1 org/jboss/netty/channel/socket/nio/NioClientSocketPipelineSink$Boss run
- Compiled : 編譯數量
- Failed : 編譯失敗數量
- Invalid : 無效數量
- Time : 編譯耗時
- FailedType : 失敗類型
- FailedMethod : 失敗方法的全限定名
-gc
垃圾回收堆的行為統計,常用命令。
$ ./jstat -gc 21332 S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT 26176.0 26176.0 0.0 3352.3 209792.0 29733.0 262144.0 31656.1 53632.0 51814.7 6528.0 6124.3 417 3.690 0 0.000 3.690
C即Capacity 總容量,U即Used 已使用的容量
- S0C : survivor0區的總容量
- S1C : survivor1區的總容量
- S0U : survivor0區已使用的容量
- S1C : survivor1區已使用的容量
- EC : Eden區的總容量
- EU : Eden區已使用的容量
- OC : Old區的總容量
- OU : Old區已使用的容量
- PC : 當前perm的容量 (KB)
- PU : perm的使用 (KB)
- YGC : 新生代垃圾回收次數
- YGCT : 新生代垃圾回收時間
- FGC : 老年代垃圾回收次數
- FGCT : 老年代垃圾回收時間
- GCT : 垃圾回收總消耗時間
$ ./jstat -gc 21332 2000 20
這個命令意思就是每隔2000ms輸出1262的gc情況,一共輸出20次。
-gccapacity
同-gc,不過還會輸出Java堆各區域使用到的最大、最小空間。
$ ./jstat -gccapacity 21332 NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC 262144.0 262144.0 262144.0 26176.0 26176.0 209792.0 262144.0 262144.0 262144.0 262144.0 0.0 1095680.0 53632.0 0.0 1048576.0 6528.0 417 0
- NGCMN : 新生代占用的最小空間
- NGCMX : 新生代占用的最大空間
- OGCMN : 老年代占用的最小空間
- OGCMX : 老年代占用的最大空間
- OGC:當前年老代的容量 (KB)
- OC:當前年老代的空間 (KB)
- PGCMN : perm占用的最小空間
- PGCMX : perm占用的最大空間
-gcutil
同-gc,不過輸出的是已使用空間占總空間的百分比。
$ ./jstat -gcutil 21332 S0 S1 E O M CCS YGC YGCT FGC FGCT GCT 0.00 12.81 14.17 12.08 96.61 93.82 417 3.690 0 0.000 3.690
-gccause
垃圾收集統計概述(同-gcutil),附加最近兩次垃圾回收事件的原因。
$ ./jstat -gccause 21332 S0 S1 E O M CCS YGC YGCT FGC FGCT GCT LGCC GCC 0.00 12.81 14.22 12.08 96.61 93.82 417 3.690 0 0.000 3.690 Allocation Failure No GC
- LGCC:最近垃圾回收的原因
- GCC:當前垃圾回收的原因
-gcnew
統計新生代的行為。
$ ./jstat -gcnew 21332 S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT 26176.0 26176.0 0.0 3352.3 6 6 13088.0 209792.0 30207.4 417 3.690
- TT:Tenuring threshold(提升閾值)
- MTT:最大的tenuring threshold
- DSS:survivor區域大小 (KB)
-gcnewcapacity
新生代與其相應的內存空間的統計。
$ ./jstat -gcnewcapacity 21332 NGCMN NGCMX NGC S0CMX S0C S1CMX S1C ECMX EC YGC FGC 262144.0 262144.0 262144.0 26176.0 26176.0 26176.0 26176.0 209792.0 209792.0 417 0
- NGC:當前年輕代的容量 (KB)
- S0CMX:最大的S0空間 (KB)
- S0C:當前S0空間 (KB)
- ECMX:最大eden空間 (KB)
- EC:當前eden空間 (KB)
-gcold
統計舊生代的行為。
$ ./jstat -gcold 21332 MC MU CCSC CCSU OC OU YGC FGC FGCT GCT 53632.0 51814.7 6528.0 6124.3 262144.0 31656.1 417 0 0.000 3.690
-gcoldcapacity
統計舊生代的大小和空間。
$ ./jstat -gcoldcapacity 21332 OGCMN OGCMX OGC OC YGC FGC FGCT GCT 262144.0 262144.0 262144.0 262144.0 417 0 0.000 3.690
-printcompilation
hotspot編譯方法統計。
$ ./jstat -printcompilation 21332 Compiled Size Type Method 10998 2602 1 org/springframework/web/util/UrlPathHelper getPathWithinApplication
- Compiled:被執行的編譯任務的數量
- Size:方法字節碼的字節數
- Type:編譯類型
- Method:編譯方法的類名和方法名。類名使用"/" 代替 "." 作為空間分隔符. 方法名是給出類的方法名. 格式是一致於HotSpot - XX:+PrintComplation 選項
三、jmap:Java內存印象工具
jmap(JVM Memory Map)命令用於生成heap dump文件,如果不使用這個命令,還闊以使用-XX:+HeapDumpOnOutOfMemoryError參數來讓虛擬機出現OOM的時候·自動生成dump文件。 jmap不僅能生成dump文件,還闊以查詢finalize執行隊列、Java堆和永久代的詳細信息,如當前使用率、當前使用的是哪種收集器等。
命令格式:
jmap [ option ] vmid
jmap工具主要選項:
選項 | 作用 |
-dump | 生成堆轉儲快照 |
-finalizerinfo | 顯示在F-Queue隊列等待Finalizer線程執行finalizer方法的對象 |
-heap | 顯示Java堆詳細信息 |
-histo | 顯示堆中對象的統計信息 |
-permstat | 以ClassLoader為統計口徑顯示永久代內存狀態。只在Linux/Solaris平台下有效 |
-F | 當-dump沒有響應時,強制生成dump快照 |
option參數詳解
-dump
常用格式:
-dump::live,format=b,file=<filename> pid
dump堆到文件,format指定輸出格式,live指明是活着的對象,file指定文件名。
$ ./jmap -dump:live,format=b,file=dump.hprof 21332 Dumping heap to /home/ubuntu/app/jdk/bin/dump.hprof ... Heap dump file created
dump.hprof這個后綴是為了后續可以直接用MAT(Memory Anlysis Tool)打開。
-finalizerinfo
打印等待回收對象的信息。
$ sudo ./jmap -finalizerinfo 21332 Attaching to process ID 21332, please wait... Debugger attached successfully. Server compiler detected. JVM version is 25.161-b12 Number of objects pending for finalization: 0
可以看到當前F-QUEUE隊列中並沒有等待Finalizer線程執行finalizer方法的對象。
-heap
打印heap的概要信息,GC使用的算法,heap的配置及wise heap的使用情況,可以用此來判斷內存目前的使用情況以及垃圾回收情況。
$ sudo ./jmap -heap 21332 Attaching to process ID 21332, please wait... Debugger attached successfully. Server compiler detected. JVM version is 25.161-b12 using parallel threads in the new generation. using thread-local object allocation. Concurrent Mark-Sweep GC Heap Configuration: MinHeapFreeRatio = 40 MaxHeapFreeRatio = 70 MaxHeapSize = 536870912 (512.0MB) NewSize = 268435456 (256.0MB) MaxNewSize = 268435456 (256.0MB) OldSize = 268435456 (256.0MB) NewRatio = 2 SurvivorRatio = 8 MetaspaceSize = 134217728 (128.0MB) CompressedClassSpaceSize = 1073741824 (1024.0MB) MaxMetaspaceSize = 268435456 (256.0MB) G1HeapRegionSize = 0 (0.0MB) Heap Usage: New Generation (Eden + 1 Survivor Space): capacity = 241631232 (230.4375MB) used = 4158608 (3.9659576416015625MB) free = 237472624 (226.47154235839844MB) 1.721055662208435% used Eden Space: capacity = 214827008 (204.875MB) used = 4158608 (3.9659576416015625MB) free = 210668400 (200.90904235839844MB) 1.9357938458091823% used From Space: capacity = 26804224 (25.5625MB) used = 0 (0.0MB) free = 26804224 (25.5625MB) 0.0% used To Space: capacity = 26804224 (25.5625MB) used = 0 (0.0MB) free = 26804224 (25.5625MB) 0.0% used concurrent mark-sweep generation: capacity = 268435456 (256.0MB) used = 26038384 (24.832138061523438MB) free = 242397072 (231.16786193847656MB) 9.700053930282593% used 20159 interned Strings occupying 2604800 bytes.
可以很清楚的看到Java堆中各個區域目前的情況。
-histo
打印堆的對象統計,包括對象數、內存大小等等 (因為在dump:live前會進行full gc,如果帶上live則只統計活對象,因此不加live的堆大小要大於加live堆的大小 )。
$ ./jmap -histo:live 21332 | more num #instances #bytes class name ---------------------------------------------- 1: 55397 8014576 [C 2: 2561 7430632 [B 3: 54263 1302312 java.lang.String 4: 9892 1102904 java.lang.Class 5: 20234 647488 java.util.concurrent.ConcurrentHashMap$Node 6: 9364 526024 [Ljava.lang.Object; 7: 5179 455752 java.lang.reflect.Method 8: 11743 375776 java.util.HashMap$Node 9: 3925 328232 [Ljava.util.HashMap$Node; 10: 7953 318120 java.util.LinkedHashMap$Entry 11: 228 260424 [Ljava.util.concurrent.ConcurrentHashMap$Node; 12: 14883 238128 java.lang.Object 13: 4078 228368 java.util.LinkedHashMap 14: 3464 148784 [I 15: 2192 109768 [Ljava.lang.String;
xml class name是對象類型,說明如下:
B byte
C char
D double
F float
I int
J long
Z boolean
[ 數組,如[I表示int[]
[L+類名 其他對象
-permstat
印Java堆內存的永久保存區域的類加載器的智能統計信息。對於每個類加載器而言,它的名稱、活躍度、地址、父類加載器、它所加載的類的數量和大小都會被打印。此外,包含的字符串數量和大小也會被打印。
-F
強制模式。如果指定的pid沒有響應,請使用jmap -dump或jmap -histo選項。此模式下,不支持live子選項。
四、jhat:虛擬機堆轉儲快照分析工具
jhat(JVM Heap Analysis Tool)命令是與jmap搭配使用,用來分析jmap生成的dump,jhat內置了一個微型的HTTP/HTML服務器,生成dump的分析結果后,可以在瀏覽器中查看。在此要注意,一般不會直接在服務器上進行分析,因為jhat是一個耗時並且耗費硬件資源的過程,一般把服務器生成的dump文件復制到本地或其他機器上進行分析。
命令格式:
jhat [dumpfile]
jstat工具主要選項
選項 | 作用 |
-stack | false|true 關閉對象分配調用棧跟蹤(tracking object allocation call stack)。 如果分配位置信息在堆轉儲中不可用. 則必須將此標志設置為 false. 默認值為 true. |
-refs | false|true 關閉對象引用跟蹤(tracking of references to objects)。 默認值為 true. 默認情況下, 返回的指針是指向其他特定對象的對象,如反向鏈接或輸入引用(referrers or incoming references), 會統計/計算堆中的所有對象。 |
-port | port-number 設置 jhat HTTP server 的端口號. 默認值 7000. |
-exclude | exclude-file 指定對象查詢時需要排除的數據成員列表文件(a file that lists data members that should be excluded from the reachable objects query)。 例如, 如果文件列列出了 java.lang.String.value , 那么當從某個特定對象 Object o 計算可達的對象列表時, 引用路徑涉及 java.lang.String.value 的都會被排除。 |
-baseline | exclude-file 指定一個基准堆轉儲(baseline heap dump)。 在兩個 heap dumps 中有相同 object ID 的對象會被標記為不是新的(marked as not being new). 其他對象被標記為新的(new). 在比較兩個不同的堆轉儲時很有用. |
-debug | int 設置 debug 級別. 0 表示不輸出調試信息。 值越大則表示輸出更詳細的 debug 信息. |
-version | 啟動后只顯示版本信息就退出 |
-J< flag > | 因為 jhat 命令實際上會啟動一個JVM來執行, 通過 -J 可以在啟動JVM時傳入一些啟動參數. 例如, -J-Xmx512m 則指定運行 jhat 的Java虛擬機使用的最大堆內存為 512 MB. 如果需要使用多個JVM啟動參數,則傳入多個 -Jxxxxxx. |
示例:
$ ./jhat -J-Xmx512m dump.hprof Reading from dump.hprof... Dump file created Wed Aug 15 23:41:00 CST 2018 Snapshot read, resolving... Resolving 330324 objects... Chasing references, expect 66 dots.................................................................. Eliminating duplicate references.................................................................. Snapshot resolved. Started HTTP server on port 7000 Server is ready.
中間的-J-Xmx512m是在dump快照很大的情況下分配512M內存去啟動HTTP服務器,運行完之后就可在瀏覽器打開Http://localhost:7000進行快照分析 堆快照分析主要在最后面的Heap Histogram里,里面根據class列出了dump的時候所有存活對象。
分析同樣一個dump快照,MAT需要的額外內存比jhat要小的多的多,所以建議使用MAT來進行分析,當然也看個人偏好。
分析
打開瀏覽器Http://localhost:7000,該頁面提供了幾個查詢功能可供使用:
All classes including platform Show all members of the rootset Show instance counts for all classes (including platform) Show instance counts for all classes (excluding platform) Show heap histogram Show finalizer summary Execute Object Query Language (OQL) query
一般查看堆異常情況主要看這個兩個部分: Show instance counts for all classes (excluding platform),平台外的所有對象信息。如下圖:
Show heap histogram 以樹狀圖形式展示堆情況。如下圖:
具體排查時需要結合代碼,觀察是否大量應該被回收的對象在一直被引用或者是否有占用內存特別大的對象無法被回收。
一般情況,會down到客戶端用工具來分析。
五、jstack:Java堆棧跟蹤工具
jstack用於生成java虛擬機當前時刻的線程快照。線程快照是當前java虛擬機內每一條線程正在執行的方法堆棧的集合,生成線程快照的主要目的是定位線程出現長時間停頓的原因,如線程間死鎖、死循環、請求外部資源導致的長時間等待等。 線程出現停頓的時候通過jstack來查看各個線程的調用堆棧,就可以知道沒有響應的線程到底在后台做什么事情,或者等待什么資源。 如果java程序崩潰生成core文件,jstack工具可以用來獲得core文件的java stack和native stack的信息,從而可以輕松地知道java程序是如何崩潰和在程序何處發生問題。另外,jstack工具還可以附屬到正在運行的java程序中,看到當時運行的java程序的java stack和native stack的信息, 如果現在運行的java程序呈現hung的狀態,jstack是非常有用的。
jstack命令格式:
jstack [ option ] vmid
jstack工具主要選項:
選項 | 作用 |
-F | 當正常輸出請求不被響應時,強制輸出線程堆棧 |
-l | 除堆棧外,顯示關於鎖的附加信息 |
-m | 如果調用到本地方法的話,可以顯示C/C++的堆棧 |
示例:
$ ./jstack -l 21332 | more 2018-08-16 00:15:47 Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.161-b12 mixed mode): "Attach Listener" #134 daemon prio=9 os_prio=0 tid=0x00007f57e415f000 nid=0x513a waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE Locked ownable synchronizers: - None "DubboResponseTimeoutScanTimer" #69 daemon prio=5 os_prio=0 tid=0x00007f57f800b800 nid=0x54c2 sleeping[0x00007f57d230d000] java.lang.Thread.State: TIMED_WAITING (sleeping) at java.lang.Thread.sleep(Native Method) at com.alibaba.dubbo.remoting.exchange.support.DefaultFuture$RemotingInvocationTimeoutScan.run(DefaultFuture.java:296) at java.lang.Thread.run(Thread.java:748) Locked ownable synchronizers: - None "dubbo-remoting-client-heartbeat-thread-2" #68 daemon prio=5 os_prio=0 tid=0x00007f57f8008800 nid=0x53eb waiting on condition [0x00007f57d0ef5000] java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for <0x00000000f037a018> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039) at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1088) at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809) at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748)
六、jinfo:Java配置信息工具
jinfo(JVM Configuration info)這個命令作用是實時查看和調整虛擬機運行參數。 之前的jps -v口令只能查看到顯示指定的參數,如果想要查看未被顯示指定的參數的值就要使用jinfo口令。
jinfo命令格式:
jinfo [ option ] pid
jinfo工具主要選項:
選項 | 作用 |
-flag | 輸出指定args參數的值 |
-flags | 不需要args參數,輸出所有JVM參數的值 |
-sysprops | 輸出系統屬性,等同於System.getProperties() |
示例:
$ sudo ./jinfo -flags 21332 Attaching to process ID 21332, please wait... Debugger attached successfully. Server compiler detected. JVM version is 25.161-b12 Non-default VM flags: -XX:CICompilerCount=2 -XX:CMSInitiatingOccupancyFraction=75 -XX:+DisableExplicitGC -XX:GCLogFileSize=10485760 -XX:HeapDumpPath=null -XX:InitialHeapSize=536870912 -XX:+ManagementServer -XX:MaxHeapSize=536870912 -XX:MaxMetaspaceSize=268435456 -XX:MaxNewSize=268435456 -XX:MaxTenuringThreshold=6 -XX:MetaspaceSize=134217728 -XX:MinHeapDeltaBytes=196608 -XX:NewSize=268435456 -XX:NumberOfGCLogFiles=30 -XX:OldPLABSize=16 -XX:OldSize=268435456 -XX:+PrintGC -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:ThreadStackSize=512 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseConcMarkSweepGC -XX:+UseGCLogFileRotation -XX:+UseParNewGC Command line: -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=1980 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Xms512M -Xmx512M -Xss512K -XX:NewSize=256M -XX:MetaspaceSize=128M -XX:MaxMetaspaceSize=256M -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -XX:+DisableExplicitGC -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -Xloggc:logs/warehouse_gateway_gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=30 -XX:GCLogFileSize=10M -XX:HeapDumpPath=logs/warehouse_gateway_dump.hprof -Djava.library.path=lib -Dwrapper.key=kQiO5p_Fz3KA0uhJ -Dwrapper.port=32001 -Dwrapper.jvm.port.min=31000 -Dwrapper.jvm.port.max=31999 -Dwrapper.pid=21330 -Dwrapper.version=3.2.3 -Dwrapper.native_library=wrapper -Dwrapper.service=TRUE -Dwrapper.cpu.timeout=10 -Dwrapper.jvmid=1