เครื่องมือบรรทัดคำสั่งเพื่อค้นหา Java Heap Size และหน่วยความจำที่ใช้ (Linux)?


171

มีเครื่องมือบรรทัดคำสั่ง (Linux) เพื่อตรวจสอบขนาดฮีป (และหน่วยความจำที่ใช้) ของ Java Application หรือไม่?

ฉันลองผ่าน jmap แต่มันให้ข้อมูล เกี่ยวกับพื้นที่หน่วยความจำภายในเช่น Eden / PermGen เป็นต้นซึ่งไม่มีประโยชน์สำหรับฉัน

ฉันกำลังมองหาบางสิ่งที่ชอบ:

  • หน่วยความจำสูงสุด: 1GB
  • หน่วยความจำขั้นต่ำ: 256 MB
  • หน่วยความจำฮีป: 700 MB
  • หน่วยความจำที่ใช้แล้ว: 460 MB

นั่นคือทั้งหมดที่ ฉันรู้ว่าฉันเห็นสิ่งนี้ใน JConsole ฯลฯ แต่ฉันต้องการเครื่องมือบรรทัดคำสั่ง (ไม่สามารถเปิดใช้งาน JMX ฯลฯ )

คุณรู้จักเครื่องมือ / คำสั่งดังกล่าวหรือไม่?

คำตอบ:


149

แต่ละกระบวนการ Java มี a pidซึ่งคุณต้องค้นหาด้วยjpsคำสั่งก่อน

เมื่อคุณมี pid คุณสามารถใช้jstat -gc [insert-pid-here]เพื่อค้นหาสถิติพฤติกรรมของกองขยะที่เก็บรวบรวม

  • jstat -gccapacity [insert-pid-here] จะนำเสนอข้อมูลเกี่ยวกับการสร้างพูลหน่วยความจำและความสามารถด้านพื้นที่

  • jstat -gcutil [insert-pid-here]จะนำเสนอการใช้ประโยชน์ของแต่ละรุ่นเป็นเปอร์เซ็นต์ของความจุ มีประโยชน์ในการดูภาพรวมการใช้งาน

ดูเอกสาร jstatบนเว็บไซต์ของ Oracle


11
มีคำแนะนำว่าjstatควรใช้ตัวเลือกใดเพื่อตรวจสอบการใช้งานหน่วยความจำโดยรวมของ JVM หรือไม่ สมมติว่าคุณเริ่มต้น JVM ด้วยXms=4gและXmx=4gคุณต้องการดูว่ามีการใช้หน่วยความจำเท่าใด
basZero

1
"jstat -gcutil <pid> 250 N" มีประโยชน์มากในการรับตัวอย่าง N ที่มีช่วงเวลา 250ms และแสดงผลลัพธ์เป็นเปอร์เซ็นต์สำหรับพื้นที่ว่างที่สอดคล้องกัน ขอบคุณ
Kerem

3
มูลค่า noting อ้างจากjstatออราเคิล Java 8 คู่มือหน้าThis command is experimental and unsupported :
patryk.beza

1
awk 'print {$3+$4+$6+$8}'สามารถพิมพ์สรุปการใช้งานบนคอลัมน์ jstat ของ Java 8
cybersoft

มีปัญหากับคำตอบอื่น ๆ แต่พื้นฐานps -ef | grep javaแสดงให้ฉันเห็น vm args ซึ่งในกรณีของฉันรวมถึงค่า -Xmx ซึ่งเป็นสิ่งที่ฉันต้องการ
xdhmoore

66

jvmtopเป็นเครื่องมือบรรทัดคำสั่งซึ่งให้มุมมองแบบสดๆในหลาย ๆ เมตริกรวมถึงฮีป

ตัวอย่างเอาต์พุตของโหมดภาพรวม VM:

 JvmTop 0.3 alpha (expect bugs)  amd64  8 cpus, Linux 2.6.32-27, load avg 0.12
 http://code.google.com/p/jvmtop

  PID MAIN-CLASS      HPCUR HPMAX NHCUR NHMAX    CPU     GC    VM USERNAME   #T DL
 3370 rapperSimpleApp  165m  455m  109m  176m  0.12%  0.00% S6U37 web        21
11272 ver.resin.Resin [ERROR: Could not attach to VM]
27338 WatchdogManager   11m   28m   23m  130m  0.00%  0.00% S6U37 web        31
19187 m.jvmtop.JvmTop   20m 3544m   13m  130m  0.93%  0.47% S6U37 web        20
16733 artup.Bootstrap  159m  455m  166m  304m  0.12%  0.00% S6U37 web        46

แน่นอนมันเป็นเครื่องมือที่ยอดเยี่ยมชนิดของฮ็อพ แต่ด้วยเมทริกจาก jstat ขอขอบคุณสำหรับข้อเสนอแนะ @Malwasser
oski86

65

คำสั่งนี้แสดงขนาดฮีพที่ตั้งค่าเป็นไบต์

java -XX:+PrintFlagsFinal -version | grep HeapSize

มันใช้งานได้กับ Amazon AMI บน EC2 เช่นกัน


26
สิ่งนี้ไม่ตอบคำถามซึ่งถามวิธีการตรวจสอบการใช้ฮีปของกระบวนการโดยเฉพาะ คำสั่งที่นี่แสดงรายการค่าเริ่มต้นของ JVM ในทุกกระบวนการ
Madbreaks

10
แต่มันเป็นคำตอบที่มีประโยชน์มากสำหรับฉันที่มาที่หน้านี้ผ่านการค้นหาโดย Google เกี่ยวกับวิธีหาขนาดฮีปส่วนกลาง
Johan

@jumping_monkey ไม่ใช่ทางอ้อมไม่ถูกต้อง หากสิ่งที่คุณพูดเป็นความจริงคำตอบควรได้รับการแก้ไขหรือคุณควรเพิ่มคำตอบใหม่
Madbreaks

42

ลองใช้งานได้ใน Ubuntu และ RedHat:

java -XX:+PrintFlagsFinal -version | grep -iE 'HeapSize|PermSize|ThreadStackSize'

สำหรับ Windows:

java -XX:+PrintFlagsFinal -version | findstr /i "HeapSize PermSize ThreadStackSize"

สำหรับ Mac

java -XX:+PrintFlagsFinal -version | grep -iE 'heapsize|permsize|threadstacksize'

เอาต์พุตของคำสั่งทั้งหมดนี้คล้ายกับเอาต์พุตด้านล่าง:

uintx InitialHeapSize                          := 20655360        {product}
uintx MaxHeapSize                              := 331350016       {product}
uintx PermSize                                  = 21757952        {pd product}
uintx MaxPermSize                               = 85983232        {pd product}
intx ThreadStackSize                           = 1024            {pd product}
java version "1.7.0_05"
Java(TM) SE Runtime Environment (build 1.7.0_05-b05)
Java HotSpot(TM) 64-Bit Server VM (build 23.1-b03, mixed mode)

ในการค้นหาขนาดเป็น MB ให้แบ่งค่าด้วย (1024 * 1024)


วิธีค้นหาการใช้งานหน่วยความจำคั่นด้วย heap, permsize, ... ของกระบวนการ java เฉพาะด้วย pid?
Gary Gauh

3
@GaryGauh นี่คือขนาดฮีปเริ่มต้น ในการค้นหาการใช้แอปพลิเคชันที่ทำงานอยู่คุณควรทำภายในรหัสหรือคุณสามารถใช้ jconsole นี่คือสิ่งที่ฉันรู้ว่าควรมีวิธีอื่น ๆ อีกมากมาย
padippist

2
ใช้jstat -gc <vmid>สำหรับเรียกใช้แอพพลิเคชั่น
Micha Wiedenmann

27

โดยไม่ต้องใช้ JMX ซึ่งเป็นเครื่องมือที่ใช้ส่วนใหญ่สิ่งที่คุณทำได้คือ

jps -lvm

และอนุมานได้ว่าการตั้งค่าจะมาจากตัวเลือกบรรทัดคำสั่ง

คุณไม่สามารถรับข้อมูลแบบไดนามิกหากไม่มี JMX เป็นค่าเริ่มต้น แต่คุณสามารถเขียนบริการของคุณเองเพื่อทำสิ่งนี้

BTW: ฉันชอบใช้ VisualVM มากกว่า JConsole


25

- มีเครื่องมือบรรทัดคำสั่งกับด้านการมองเห็นเป็นJVM-mon มันเป็นเครื่องมือตรวจสอบ JVM สำหรับบรรทัดคำสั่งที่ disaplys:

  • การใช้งานฮีปขนาดและสูงสุด
  • กระบวนการ jvm
  • การใช้ cpu และ GC
  • หัวข้อยอดนิยม

ตัวชี้วัดและแผนภูมิจะอัพเดทขณะที่เครื่องมือเปิดอยู่

ตัวอย่าง: JVM-mon


1
เพิ่งทราบว่า jvm-mon ทำงานเฉพาะสำหรับ Java8
tmanolatos

1
^ มีรุ่นใหม่ที่รองรับ Java 11
Andrejs

11

มาปาร์ตี้ช้า แต่วิธีแก้ปัญหาที่ง่ายมากคือการใช้สคริปต์ jpsstat.sh มันให้ง่ายสดหน่วยความจำในปัจจุบัน , หน่วยความจำสูงสุดและใช้ซีพียูรายละเอียด

  • ไปที่โปรเจ็กต์ GitHubและดาวน์โหลดไฟล์jpsstat.sh
  • คลิกขวาที่jpsstat.shและกลับไปข้างสิทธิ์แท็บและทำให้มันปฏิบัติการ
  • ตอนนี้เรียกใช้สคริปต์โดยใช้คำสั่งต่อไปนี้. / jpsstat.sh

นี่คือผลลัพธ์ตัวอย่างของสคริปต์ -

=====  ======  =======  =======  =====
 PID    Name   CurHeap  MaxHeap  %_CPU
=====  ======  =======  =======  =====
2777   Test3      1.26     1.26    5.8
2582   Test1      2.52     2.52    8.3
2562   Test2      2.52     2.52    6.4

ดูเหมือนจะไม่ทำงานนอกกรอบบน SUSE Linux (บรรทัดที่ 38: ประกาศ: -A: ตัวเลือกที่ไม่ถูกต้อง)
Chris

ดูเหมือนว่าคุณจะได้รับข้อผิดพลาดในการประกาศอาเรย์แบบเชื่อมโยงซึ่งต้องการ bash> = 4 นอกจากนี้ปัญหาอื่นอาจเกิดจากการรันสคริปต์ในชื่อ "sh jpsstat.sh" หากเป็นเช่นนั้นให้ลองเรียกใช้สคริปต์ในชื่อ "./jpsstat.sh"
amarjeetAnand

9

ในกรณีของฉันฉันต้องตรวจสอบธงภายในคอนเทนเนอร์นักเทียบท่าซึ่งไม่มีสาธารณูปโภคพื้นฐานส่วนใหญ่ (ps, pstree ... )

ใช้jpsฉันได้รับ PID ของ JVM ทำงาน (ในกรณีของฉัน 1) จากนั้นjcmd 1 VM.flagsฉันได้รับธงจาก JVM ที่กำลังทำงานอยู่

มันขึ้นอยู่กับคำสั่งที่คุณมี แต่สิ่งนี้อาจช่วยใครซักคน :)


8

จากJava8 ขึ้นไปคุณสามารถใช้คำสั่งด้านล่าง:

jcmd JAVA_PROCESS_IDGC.heap_info

คุณอาจอ้างถึงจำนวนหน่วยความจำทั้งหมดและหน่วยความจำที่ใช้แล้ว

Sample Command And Output: jcmd 9758 GC.heap_info

PSYoungGen  total 1579520K, used 487543K [0x0000000751d80000, 0x00000007c0000000, 0x00000007c0000000)
  eden space 1354240K, 36% used [0x0000000751d80000,0x000000076f99dc40,0x00000007a4800000)
  from space 225280K, 0% used [0x00000007b2400000,0x00000007b2400000,0x00000007c0000000)
  to   space 225280K, 0% used [0x00000007a4800000,0x00000007a4800000,0x00000007b2400000)
ParOldGen       total 3610112K, used 0K [0x0000000675800000, 0x0000000751d80000, 0x0000000751d80000)
  object space 3610112K, 0% used [0x0000000675800000,0x0000000675800000,0x0000000751d80000)
Metaspace       used 16292K, capacity 16582K, committed 16896K, reserved 1064960K
  class space    used 1823K, capacity 1936K, committed 2048K, reserved 1048576K

สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับคำสั่ง jcmd โปรดไปที่ลิงก์: https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr006.html


1
คุณต้องแก้ไขความคิดเห็นของคุณ GC.heap_info มีให้ใน Java 9 ขึ้นไป ไม่สามารถใช้งานได้ใน Java 8 ดูเธรดอื่นที่นี่: stackoverflow.com/questions/41891127/…
Pavel Molchanov

@PavelMolchanov ฉันสามารถใช้คำสั่งใน jdk1.8.0_172 /Library/Java/JavaVirtualMachines/jdk1.8.0_172.jdk/Contents/Home/bin/jcmd 98270 GC.heap_info กรุณาถ้าคุณอาจเพิ่มข้อมูลไปยังหัวข้อที่อ้างอิงและฉันไม่ได้มีชื่อเสียงพอที่จะเพิ่มความคิดเห็นที่นั่น
vaibhav gupta

คุณใช้ Mac ไหม? คุณใช้ Oracle JDK หรือไม่ ผมไม่ทราบวิธีที่จะสามารถใช้ได้ใน jdk1.8.0_172 ของคุณ, Oracle เอกสารคุณลักษณะนี้เฉพาะในชวา 9 ขึ้นไป: docs.oracle.com/javase/9/tools/jcmd.htm ไม่ได้อยู่ในเอกสารของ Oracle JDK สำหรับ Java 8 ไม่ได้กล่าวถึงในลิงก์ที่คุณระบุไว้ด้านล่าง: docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/
Pavel Molchanov

อีกหนึ่งคำถาม โปรดตรวจสอบรุ่น JDK ที่ใช้กระบวนการ 98270 ในตัวอย่างของคุณ jcmd ได้รับคำสั่งจาก JVM ของกระบวนการ (ในกรณีของคุณ 98270) หากกระบวนการ 98270 ดำเนินการกับ JDK (JDK 9 หรือสูงกว่า) ที่แตกต่างกันคุณจะเห็นคำสั่ง GC.heap_info พร้อมใช้งานแม้ใน JCMD เองนั้นมาจาก Java 8 คำสั่งที่ใช้ได้อาจแตกต่างกันสำหรับกระบวนการที่แตกต่างกัน หากต้องการรับคำสั่งที่พร้อมใช้งานให้ดำเนินการ: jcmp <PID> ช่วย
Pavel Molchanov

1
FWIW GC.heap_infoพร้อมใช้งานใน OpenJDK 8 อย่างแน่นอน อาจเป็นรุ่นล่าสุดเท่านั้น? ฉันใช้อันนี้: 8u191-b12-2ubuntu0.18.04.1
ต่อ Lundberg

7

วิธีใดก็ตามที่ควรให้หมายเลขเดียวกันกับคุณ เป็นความคิดที่ดีที่จะจัดสรรฮีปที่ใช้-X..m -X..xสำหรับทุกรุ่น จากนั้นคุณสามารถรับประกันและทำ ps เพื่อดูว่าพารามิเตอร์ใดถูกส่งผ่านและถูกนำมาใช้

สำหรับการใช้หน่วยความจำจริงคุณสามารถเปรียบเทียบ VIRT (จัดสรรและแชร์) และ RES (ใช้จริง) เปรียบเทียบกับค่า jstat เช่นกัน:

สำหรับ Java 8 ให้ดูjstatสำหรับค่าเหล่านี้จริง ๆ แล้วหมายถึง สมมติว่าคุณเรียกใช้คลาสที่เรียบง่ายโดยไม่มี mmap หรือการประมวลผลไฟล์

$ jstat -gccapacity 32277
 NGCMN    NGCMX     NGC     S0C   S1C       EC      OGCMN      OGCMX       OGC         OC       MCMN     MCMX      MC     CCSMN    CCSMX     CCSC    YGC    FGC
215040.0 3433472.0  73728.0  512.0  512.0  67072.0   430080.0  6867968.0   392704.0   392704.0      0.0 1083392.0  39680.0      0.0 1048576.0   4864.0   7225     2
$ jstat -gcutil 32277
  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT
  6.25   0.00   7.96  18.21  98.01  95.29   7228   30.859     2    0.173   31.032

สูงสุด :

     NGCMX + S0C + S1C + EC    + OGCMX   + MCMX    + CCSMX
   3433472 + 512 + 512 + 67072 + 6867968 + 1083392 + 1048576 = 12 GB

(โดยประมาณใกล้กับด้านล่างถึงหน่วยความจำ VIRT)

สูงสุด (ต่ำสุด, ใช้แล้ว):

215040 + 512 + 512 + 67072 + 430080  + 39680    +  4864  = ~ 1GB

(ประมาณใกล้เคียงกับหน่วยความจำ RES)

"อย่าพูดถึงฉันในสิ่งนี้" แต่ mem VIRT นั้นใกล้เคียงหรือมากกว่าหน่วยความจำสูงสุดที่จัดสรร แต่ตราบใดที่หน่วยความจำที่ใช้นั้นว่าง / มีอยู่ในหน่วยความจำกายภาพ JVM จะไม่ส่งข้อยกเว้นหน่วยความจำ ในความเป็นจริงหน่วยความจำสูงสุดยังไม่ได้ตรวจสอบกับหน่วยความจำกายภาพในการเริ่มต้น JVM แม้ว่าจะมีการสลับบน OS คำอธิบายที่ดีของสิ่งที่หน่วยความจำเสมือนใช้จริงๆโดยกระบวนการ Java จะกล่าวถึงที่นี่


4

อันดับแรกรับ id กระบวนการหมายเลขแรกจากกระบวนการที่แสดงจากหนึ่งในรายการต่อไปนี้: (หรือเพียงใช้ps aux | grep javaถ้าคุณต้องการ)

jps -lvm

จากนั้นใช้ ID กระบวนการที่นี่:

jmap -heap $MY_PID 2>/dev/null | sed -ne '/Heap Configuration/,$p';
jmap -permstat $MY_PID

2

การใช้topคำสั่งเป็นวิธีที่ง่ายที่สุดในการตรวจสอบการใช้หน่วยความจำของโปรแกรม RESคอลัมน์แสดงหน่วยความจำกายภาพจริงที่ถูกครอบครองโดยกระบวนการ

สำหรับกรณีของฉันฉันมีไฟล์ 10g ที่อ่านใน java และทุกครั้งที่ฉันได้รับข้อยกเว้น outOfMemory สิ่งนี้เกิดขึ้นเมื่อค่าในRESคอลัมน์ถึงค่าที่ตั้งไว้ใน-Xmxตัวเลือก จากนั้นเพิ่มหน่วยความจำโดยใช้-Xmxตัวเลือกทุกอย่างเป็นไปด้วยดี


3
คำสั่ง top จะแสดงจำนวน OS ที่มอบให้กับ JVM พวกนี้ถามว่าเราจะเห็นการใช้พื้นที่ฮีปภายใน JVM ได้อย่างไร JVM กำลังใช้ 10g ไม่ได้หมายความว่าพื้นที่ฮีปจริงเต็มไปด้วยข้อมูล 10g เนื่องจาก jvm แทบจะไม่ส่งคืนหน่วยความจำกลับไปที่ระบบปฏิบัติการจากฮีปจนกว่าคุณจะฆ่ากระบวนการ
linehrr

2

ในแง่ของขนาดฮีพของ Java ใน Linux คุณสามารถใช้

ps aux | grep java

หรือ

ps -ef | grep java

และค้นหา -Xms, -Xmx เพื่อค้นหาขนาดฮีพเริ่มต้นและสูงสุดที่ระบุ

อย่างไรก็ตามหาก -Xms หรือ -Xmx ไม่มีอยู่สำหรับกระบวนการ Java ที่คุณสนใจนั่นหมายถึงกระบวนการ Java ของคุณใช้ขนาดฮีปเริ่มต้น คุณสามารถใช้คำสั่งต่อไปนี้เพื่อค้นหาขนาดเริ่มต้น

java -XX:+PrintFlagsFinal -version | grep HeapSize

หรือ jvm เฉพาะเช่น

/path/to/jdk1.8.0_102/bin/java -XX:+PrintFlagsFinal -version | grep HeapSize

และมองหา InitialHeapSize และ MaxHeapSize ซึ่งมีหน่วยเป็นไบต์


1

หากใช้ jrockit ให้ลองใช้เครื่องมือบรรทัดคำสั่ง jrcmd ตัวอย่างเช่น:

$ jrcmd 5127 print_memusage
5127:
Total mapped                  1074596KB           (reserved=3728KB)
-              Java heap       786432KB           (reserved=0KB)
-              GC tables        26316KB          
-          Thread stacks        13452KB           (#threads=34)
-          Compiled code         9856KB           (used=9761KB)
-               Internal          840KB          
-                     OS        15036KB          
-                  Other       146632KB          
-        Java class data        75008KB           (malloced=74861KB #103221 in 18709 classes)
- Native memory tracking         1024KB           (malloced=102KB #8)

สำหรับคำสั่งเพิ่มเติมเช่น heap_diagnostics ให้ใช้ "jrcmd help" เพื่อแสดงรายการ

https://blogs.oracle.com/jrockit/entry/why_is_my_jvm_process_larger_t


1
jstat -gccapacity javapid  (ex. stat -gccapacity 28745)
jstat -gccapacity javapid gaps frames (ex.  stat -gccapacity 28745 550 10 )

ตัวอย่าง O / P ของคำสั่งด้านบน

NGCMN    NGCMX     NGC     S0C  
87040.0 1397760.0 1327616.0 107520.0 

NGCMN   Minimum new generation capacity (KB).
NGCMX   Maximum new generation capacity (KB).
NGC Current new generation capacity (KB).

รับรายละเอียดเพิ่มเติมเกี่ยวกับสิ่งนี้ได้ที่http://docs.oracle.com/javase/1.5.0/docs/tooldocs/share/jstat.html


1

ไม่มีเครื่องมือดังกล่าวในการพิมพ์หน่วยความจำกองในรูปแบบตามที่คุณร้องขอจนถึงขณะนี้ เท่านั้นและวิธีเดียวที่จะพิมพ์คือการเขียนโปรแกรม Java ด้วยความช่วยเหลือของ Runtime ชั้น ,

public class TestMemory {

public static void main(String [] args) {

    int MB = 1024*1024;

    //Getting the runtime reference from system
    Runtime runtime = Runtime.getRuntime();

    //Print used memory
    System.out.println("Used Memory:" 
        + (runtime.totalMemory() - runtime.freeMemory()) / MB);

    //Print free memory
    System.out.println("Free Memory:" 
        + runtime.freeMemory() / mb);

    //Print total available memory
    System.out.println("Total Memory:" + runtime.totalMemory() / MB);

    //Print Maximum available memory
    System.out.println("Max Memory:" + runtime.maxMemory() / MB);
}

}

การอ้างอิง: https://viralpatel.net/blogs/getting-jvm-heap-size-used-memory-total-memory-using-java-runtime/


นี่มันผิด jmap -heap <pid> ให้ข้อมูลนี้
vsingh

0

ค้นหารหัสกระบวนการของกระบวนการ webapp / java ของคุณจากด้านบน ใช้ jmap heap เพื่อรับการจัดสรรฮีป ฉันทดสอบสิ่งนี้ใน AWS-Ec2 สำหรับฝักถั่วที่ยืดหยุ่น

คุณสามารถดูภาพด้านล่างฮีปสูงสุด 3GB สำหรับแอปพลิเคชัน

ป้อนคำอธิบายรูปภาพที่นี่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.