Alat baris perintah untuk menemukan Ukuran dan Memori Java Heap (Linux)?

171

Apakah ada Alat Baris Perintah (Linux) untuk memeriksa Ukuran Tumpukan (dan Memori yang Digunakan) dari Aplikasi Java?

Saya sudah mencoba melalui jmap. Tapi itu memberi info. tentang area memori internal seperti Eden / PermGen dll., yang tidak berguna bagi saya.

Saya mencari sesuatu seperti:

  • Memori Maks: 1GB
  • Memori Min: 256 MB
  • Memori Tumpukan: 700 MB
  • Memori yang Digunakan: 460 MB

Itu saja. Saya tahu bahwa saya dapat melihat ini di JConsole dll, tetapi saya memerlukan alat baris perintah (tidak dapat mengaktifkan JMX dll.)

Apakah Anda tahu alat / perintah seperti itu?

Jasper
sumber

Jawaban:

150

Setiap proses Java memiliki pid, yang pertama kali harus Anda temukan dengan jpsperintah.

Setelah Anda memiliki pid, Anda dapat menggunakan jstat -gc [insert-pid-here]untuk menemukan statistik dari perilaku tumpukan sampah yang dikumpulkan.

  • jstat -gccapacity [insert-pid-here] akan menyajikan informasi tentang pembuatan ruang memori dan kemampuan ruang.

  • jstat -gcutil [insert-pid-here]akan menyajikan pemanfaatan setiap generasi sebagai persentase dari kapasitasnya. Berguna untuk mendapatkan pandangan sekilas tentang penggunaan.

Lihat jstat docs di situs Oracle.

petani1992
sumber
11
Apakah ada rekomendasi opsi mana yang jstatharus digunakan untuk memverifikasi hanya penggunaan memori JVM secara keseluruhan? Katakanlah Anda memulai JVM dengan Xms=4gdan Xmx=4gdan Anda ingin melihat, berapa banyak memori yang sudah digunakan?
basZero
1
"jstat -gcutil <pid> 250 N" sangat berguna untuk mengambil sampel N dengan interval 250ms dan menampilkan output sebagai persentase untuk ruang yang sesuai. Terima kasih.
Kerem
3
Perlu dicatat kutipan dari jstatOracle Java 8 panduan page : This command is experimental and unsupported.
patryk.beza
1
awk 'print {$3+$4+$6+$8}'dapat mencetak ringkasan penggunaan pada kolom jstat Java 8
cybersoft
Terjadi masalah dengan jawaban lain, tetapi dasar ps -ef | grep javamenunjukkan kepada saya vm args, yang dalam kasus saya termasuk nilai -Xmx, yang saya butuhkan.
xdhmoore
66

jvmtop adalah alat baris perintah yang menyediakan tampilan langsung di beberapa metrik, termasuk heap.

Contoh output dari mode VM overview:

 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
MRalwasser
sumber
Ini memang alat yang hebat, semacam htop tetapi dengan metrik dari jstat. Terima kasih atas sarannya, @MRalwasser.
oski86
65

Perintah ini menunjukkan ukuran tumpukan yang dikonfigurasi dalam byte.

java -XX:+PrintFlagsFinal -version | grep HeapSize

Ini berfungsi di Amazon AMI di EC2 juga.

Atma
sumber
27
Ini tidak menjawab pertanyaan, yang secara khusus menanyakan cara memeriksa tumpukan penggunaan suatu proses. Perintah di sini mencantumkan standar JVM di semua proses.
Kerusakan
10
Namun, ini adalah jawaban yang sangat membantu bagi saya untuk datang ke halaman ini melalui pencarian google tentang cara menemukan ukuran tumpukan global.
Johan
@jumping_monkey bukan tidak langsung, salah. Jika apa yang Anda katakan itu benar, jawabannya harus diedit atau Anda harus merasa bebas untuk menambahkan jawaban baru.
Madbreaks
43

Coba ini berhasil di Ubuntu dan RedHat:

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

Untuk Windows:

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

Untuk Mac

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

Output dari semua perintah ini menyerupai output di bawah ini:

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)

Untuk menemukan ukuran dalam MB, bagi nilainya dengan (1024 * 1024).

padippist
sumber
Bagaimana menemukan penggunaan memori yang dipisahkan oleh heap, permsize, ... dari proses java tertentu oleh pid?
Gary Gauh
3
@ GaryGauh Ini adalah ukuran tumpukan standar. Untuk menemukan penggunaan aplikasi yang berjalan, Anda harus melakukannya dalam kode atau Anda dapat menggunakan jconsole. Ini yang saya tahu seharusnya juga ada banyak cara lain.
padippist
2
Gunakan jstat -gc <vmid>untuk menjalankan aplikasi.
Micha Wiedenmann
28

Tanpa menggunakan JMX, yang digunakan sebagian besar alat, yang bisa Anda lakukan hanyalah menggunakannya

jps -lvm

dan menyimpulkan bahwa pengaturan akan berasal dari opsi baris perintah.

Anda tidak dapat memperoleh informasi dinamis tanpa JMX secara default tetapi Anda dapat menulis layanan Anda sendiri untuk melakukan ini.

BTW: Saya lebih suka menggunakan VisualVM daripada JConsole.

Peter Lawrey
sumber
25

Ada alat baris perintah dengan aspek visual - jvm-mon . Ini adalah alat pemantauan JVM untuk baris perintah yang menghilang:

  • tumpukan penggunaan, ukuran dan maks
  • proses jvm
  • penggunaan cpu dan GC
  • utas teratas

Metrik dan bagan diperbarui saat alat terbuka.

Sampel: jvm-mon

Andrejs
sumber
1
Hanya untuk dicatat bahwa jvm-mon berjalan hanya untuk Java8
tmanolatos
1
^ Ada versi baru yang sekarang juga mendukung Java 11.
Andrejs
11

Terlambat di pesta, tetapi solusi yang sangat sederhana adalah dengan menggunakan skrip jpsstat.sh. Ini memberikan hidup sederhana saat ini memori , memori maks dan detail penggunaan cpu .

  • Goto proyek GitHub dan unduh file jpsstat.sh
  • Klik kanan pada izin jpsstat.sh dan goto tab dan buat itu bisa dieksekusi
  • Sekarang Jalankan skrip menggunakan perintah berikut ./jpsstat.sh

Berikut adalah contoh hasil skrip -

=====  ======  =======  =======  =====
 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
amarjeetAnand
sumber
tampaknya tidak bekerja di luar kotak pada SUSE Linux (baris 38: menyatakan: -A: opsi tidak valid)
Chris
sepertinya Anda mendapatkan kesalahan dalam deklarasi array asosiatif yang membutuhkan bash> = 4. Juga masalah lain mungkin karena menjalankan skrip sebagai "sh jpsstat.sh". Jika demikian, coba jalankan skrip sebagai "./jpsstat.sh".
amarjeetAnand
9

Dalam kasus saya, saya perlu memeriksa bendera di dalam wadah buruh pelabuhan yang tidak memiliki sebagian besar utilitas dasar (ps, pstree ...)

Menggunakan jpssaya mendapat PID dari JVM berjalan (dalam kasus saya 1) dan kemudian dengan jcmd 1 VM.flagssaya mendapat bendera dari JVM berjalan.

Itu tergantung pada perintah apa yang Anda miliki, tetapi ini mungkin membantu seseorang. :)

froblesmartin
sumber
8

Dari Java8 ke atas , Anda dapat menggunakan perintah di bawah ini:

jcmd JAVA_PROCESS_IDGC.heap_info

Anda dapat merujuk ke jumlah, total dan memori yang digunakan dari output.

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

Untuk detail lebih lanjut tentang perintah jcmd, kunjungi tautan: https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr006.html

vaibhav gupta
sumber
1
Anda perlu memperbaiki komentar Anda. GC.heap_info tersedia di Java 9 ke atas. Ini tidak tersedia di Java 8. Lihat utas lainnya di sini: stackoverflow.com/questions/41891127/…
Pavel Molchanov
@ PavelMolchanov Saya dapat menggunakan perintah di jdk1.8.0_172. /Library/Java/JavaVirtualMachines/jdk1.8.0_172.jdk/Contents/Home/bin/jcmd 98270 GC.heap_info. Silakan jika Anda bisa, Tambahkan info ke utas yang dirujuk serta saya tidak memiliki reputasi yang cukup untuk menambahkan komentar di sana.
vaibhav gupta
Apakah Anda menggunakan Mac? Apakah Anda menggunakan Oracle JDK? Saya tidak tahu bagaimana ini bisa tersedia di jdk1.8.0_172 Anda, Oracle mendokumentasikan fitur ini hanya di Java 9 dan lebih tinggi: docs.oracle.com/javase/9/tools/jcmd.htm . Itu tidak ada dalam dokumentasi Oracle JDK untuk Java 8. Tidak disebutkan dalam tautan yang Anda berikan di bagian bawah: docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/…
Pavel Molchanov
Satu pertanyaan lagi. Silakan periksa versi JDK yang menjalankan proses 98270 dalam contoh Anda. jcmd mendapatkan perintah yang tersedia dari JVM dari proses (dalam kasus Anda 98270). Jika proses 98270 proses dijalankan dengan JDK yang berbeda (JDK 9 atau lebih tinggi), Anda akan melihat perintah GC.heap_info tersedia bahkan di JCMD sendiri dari Java 8. Perintah yang tersedia mungkin berbeda untuk proses yang berbeda. Untuk mendapatkan perintah yang tersedia jalankan: bantuan jcmp <PID>.
Pavel Molchanov
1
FWIW, GC.heap_infopasti tersedia di OpenJDK 8 juga. Mungkin hanya di versi terbaru? Saya menggunakan ini: 8u191-b12-2ubuntu0.18.04.1
Per Lundberg
7

Setiap pendekatan harus memberi Anda nomor yang kira-kira sama. Itu selalu merupakan ide yang baik untuk mengalokasikan tumpukan menggunakan -X..m -X..xuntuk semua generasi. Anda kemudian dapat menjamin dan juga melakukan ps untuk melihat parameter apa yang dilewati dan karenanya digunakan.

Untuk penggunaan memori aktual, Anda dapat secara kasar membandingkan VIRT (dialokasikan dan dibagi) dan RES (aktual digunakan) dibandingkan dengan nilai jstat juga:

Untuk Java 8, lihat jstat untuk nilai-nilai ini sebenarnya berarti. Dengan asumsi Anda menjalankan kelas sederhana tanpa mmap atau pemrosesan file.

$ 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

Maks :

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

(kira-kira dekat dan di bawah ke memori VIRT)

Max (Min, Bekas):

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

(kira-kira dekat dengan memori RES)

"Jangan mengutip saya tentang ini" tetapi VIRT mem kira-kira mendekati atau lebih dari memori Max yang dialokasikan tetapi selama memori yang digunakan bebas / tersedia dalam memori fisik, JVM tidak melempar pengecualian memori. Bahkan, memori maks bahkan tidak diperiksa terhadap memori fisik pada startup JVM bahkan dengan swap off pada OS. Penjelasan yang lebih baik tentang apa memori virtual yang benar-benar digunakan oleh proses Java dibahas di sini .

kisna
sumber
4

Pertama-tama dapatkan id proses, nomor pertama dari proses yang terdaftar, dari salah satu dari yang berikut: (atau gunakan saja ps aux | grep java, jika Anda menginginkannya)

jps -lvm

Kemudian gunakan ID proses di sini:

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

Menggunakan topperintah adalah cara paling sederhana untuk memeriksa penggunaan memori program. RESKolom menunjukkan memori fisik nyata yang ditempati oleh suatu proses.

Untuk kasus saya, saya punya file 10g dibaca di java dan setiap kali saya keluar dari pengecualian Memory. Ini terjadi ketika nilai di RESkolom mencapai ke nilai yang ditetapkan dalam -Xmxopsi. Kemudian dengan menambah memori menggunakan -Xmxopsi semuanya berjalan dengan baik.

M. Mashaye
sumber
3
perintah top menunjukkan berapa banyak OS yang diberikan kepada JVM. orang-orang ini bertanya bagaimana kita bisa melihat tumpukan penggunaan ruang di dalam JVM. JVM menggunakan 10g tidak berarti ruang tumpukan nyata penuh dengan data 10g, karena jvm hampir tidak pernah mengembalikan memori kembali ke OS dari tumpukan sampai Anda mematikan proses.
linehrr
2

Dalam hal ukuran tumpukan Java, di Linux, Anda dapat menggunakan

ps aux | grep java

atau

ps -ef | grep java

dan cari -Xms, -Xmx untuk mengetahui ukuran heap awal dan maksimum yang ditentukan.

Namun, jika -Xms atau -Xmx tidak ada untuk proses Java yang Anda minati, itu berarti proses Java Anda menggunakan ukuran heap default. Anda dapat menggunakan perintah berikut untuk mengetahui ukuran standar.

java -XX:+PrintFlagsFinal -version | grep HeapSize

atau jvm tertentu, misalnya,

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

dan cari InitialHeapSize dan MaxHeapSize, yang dalam byte.

Yuci
sumber
1

Jika menggunakan jrockit coba alat baris perintah jrcmd. Sebagai contoh:

$ 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)

Untuk perintah lainnya, seperti heap_diagnostics, gunakan "jrcmd help" untuk mendaftarnya.

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

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

Contoh O / P dari perintah di atas

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).

Dapatkan detail lebih lanjut tentang ini di http://docs.oracle.com/javase/1.5.0/docs/tooldocs/share/jstat.html

Pravin
sumber
1

Tidak ada alat seperti itu sampai sekarang untuk mencetak memori tumpukan dalam format seperti yang Anda minta . Satu-satunya cara untuk mencetak adalah dengan menulis program java dengan bantuan Kelas 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);
}

}

referensi: https://viralpatel.net/blogs/getting-jvm-heap-size-used-memory-total-memory-using-java-runtime/

Gowtham Prasath
sumber
ini salah. jmap -heap <pid> memberikan info ini
vsingh
0

Temukan id proses dari proses webapp / java Anda dari atas. Gunakan jmap heap untuk mendapatkan alokasi heap. Saya menguji ini pada AWS-Ec2 untuk batang pohon karet elastis

Anda dapat melihat pada gambar di bawah tumpukan maksimal 3GB untuk aplikasi

masukkan deskripsi gambar di sini

vsingh
sumber