Komut satırı aracı Java yığın boyutu ve kullanılan bellek (Linux) bulmak için?


171

Bir Java Uygulamasının Öbek Boyutunu (ve Kullanılan Belleği) kontrol etmek için bir Komut Satırı Aracı (Linux) var mı?

Jmap ile denedim. Ama bilgi veriyor. benim için yararlı olmayan Eden / PermGen gibi dahili bellek alanları hakkında.

Gibi bir şey arıyorum:

  • Maksimum Bellek: 1GB
  • Min. Bellek: 256 MB
  • Yığın Bellek: 700 MB
  • Kullanılan Bellek: 460 MB

Bu kadar. Bunu JConsole vs.'de görebildiğimi biliyorum, ama bir komut satırı aracına ihtiyacım var (JMX'i etkinleştiremiyorum vb.)

Böyle bir araç / komut biliyor musunuz?

Yanıtlar:


150

Her Java işlemi, pidönce jpskomutla bulmanız gereken bir a'ya sahiptir.

Pid'i aldıktan sonra, jstat -gc [insert-pid-here]toplanan çöp yığınının davranışının istatistiklerini bulmak için kullanabilirsiniz .

  • jstat -gccapacity [insert-pid-here] bellek havuzu oluşturma ve alan özellikleri hakkında bilgi sunacak.

  • jstat -gcutil [insert-pid-here]her neslin kullanımını kapasitesinin bir yüzdesi olarak sunacaktır. Bir bakışta kullanım görünümü elde etmek için kullanışlıdır.

Oracle sitesindeki jstat belgelerine bakın .


11
Bir jstatJVM'nin sadece genel bellek kullanımını doğrulamak için hangi seçeneklerin kullanılması gerektiğine dair bir tavsiye var mı ? Diyelim ki JVM'yi başlattınız Xms=4gve Xmx=4ggörmek istiyorsunuz, bunun ne kadar hafızası kullanılıyor?
basZero

1
"jstat -gcutil <pid> 250 N", 250 ms aralıklarla N numuneleri almak ve çıktıyı karşılık gelen boşluklar için yüzde olarak görüntülemek için çok yararlı oldu. Teşekkürler.
Kerem

3
Worth dan belirterek alıntı jstatOracle Java 8 manuel sayfa : This command is experimental and unsupported.
patryk.beza

1
awk 'print {$3+$4+$6+$8}'Java 8'in jstat sütunlarında özetlenmiş kullanımı yazdırabilir
cybersoft

Diğer cevaplar ile sorun vardı, ama bir temel ps -ef | grep javavm args gösterdi ki benim durumumda -Xmx değeri, tüm ihtiyacım olan dahil.
xdhmoore

66

jvmtop , yığın da dahil olmak üzere çeşitli metriklerde canlı görüntüleme sağlayan bir komut satırı aracıdır.

VM genel bakış modunun örnek çıktısı:

 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

Gerçekten harika bir araç, htop tür ama jstat metrikleri ile. Öneri için teşekkürler, @MRalwasser.
oski86

65

Bu komut, yapılandırılmış yığın boyutlarını bayt cinsinden gösterir.

java -XX:+PrintFlagsFinal -version | grep HeapSize

EC2'de Amazon AMI üzerinde de çalışır.


27
Bu, özellikle bir işlemin yığın kullanımının nasıl denetleneceğini soran soruyu yanıtlamaz. Buradaki komut, tüm işlemler boyunca JVM varsayılanlarını listeler.
Madbreaks

10
Yine de, küresel yığın boyutunu nasıl bulacağım konusunda google arama yoluyla bu sayfaya gelmem benim için çok yararlı bir cevap.
Johan

@jumping_monkey dolaylı değil, yanlış. Söyledikleriniz doğruysa, cevap düzenlenmeli veya yeni bir cevap eklemekte özgür olmalısınız.
Madbreaks

43

Ubuntu ve RedHat'ta çalıştı:

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

Pencereler için:

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

Mac için

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

Tüm bu komutların çıktısı aşağıdaki çıktıya benzer:

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 cinsinden boyutu bulmak için değeri (1024 * 1024) ile bölün.


Belirli java işleminin yığın, izin, ... ile ayrılmış bellek kullanımı pid ile nasıl bulunur?
Gary Gauh

3
@GaryGauh Bu, varsayılan yığın boyutudur. Çalışan uygulamanın kullanımını bulmak için kod içinde yapmalısınız veya jconsole kullanabilirsiniz. Bunun başka birçok yol olması gerektiğini de biliyorum.
Ocak'ta padipist

2
jstat -gc <vmid>Çalışan uygulamalar için kullanın .
Micha Wiedenmann

28

Çoğu aracın kullandığı JMX kullanmadan, yapabileceğiniz tek şey

jps -lvm

ve ayarların komut satırı seçeneklerinden olacağını belirleyin.

Varsayılan olarak JMX olmadan dinamik bilgi alamazsınız, ancak bunu yapmak için kendi hizmetinizi yazabilirsiniz.

BTW: JConsole yerine VisualVM kullanmayı tercih ediyorum.


25

Görsel bir yönü olan bir komut satırı aracı var - jvm-mon . Komut satırı için hayal kırıklığına uğratan bir JVM izleme aracıdır:

  • yığın kullanımı, boyut ve maks
  • jvm süreçleri
  • cpu ve GC kullanımı
  • üst konular

Araç açıkken metrikler ve grafikler güncellenir.

Örneklem: jvm-mon


1
Sadece jvm-mon sadece Java8 için çalışır unutmayın
tmanolatos

1
^ Artık Java 11'i de destekleyen yeni bir sürüm var
Andrejs

11

Partide geç, ama çok basit bir çözüm jpsstat.sh betiği kullanmaktır. Basit bir canlı akım belleği , maksimum bellek ve işlemci kullanım ayrıntıları sağlar.

  • Goto GitHub proje ve indirmek jpsstat.sh dosyasını
  • Jpsstat.sh dosyasına sağ tıklayın ve izinler sekmesine gidin ve çalıştırılabilir yapın
  • Şimdi aşağıdaki komutu kullanarak komut dosyasını çalıştırın ./jpsstat.sh

İşte komut dosyasının örnek çıktısı -

=====  ======  =======  =======  =====
 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'ta kutudan çıkmış gibi görünmüyor (satır 38: beyan: -A: geçersiz seçenek)
Chris

bash> = 4 gerektiren ilişkilendirilebilir dizi bildiriminde hata alıyorsunuz gibi geliyor. Ayrıca başka bir sorun komut dosyası "sh jpsstat.sh" olarak çalıştırılmasından kaynaklanıyor olabilir. Öyleyse, komut dosyasını "./jpsstat.sh" olarak çalıştırmayı deneyin.
amarjeetAnand

9

Benim durumumda, temel yardımcı programların çoğuna sahip olmayan bir docker konteyneri içindeki bayrakları kontrol etmem gerekiyordu (ps, pstree ...)

Kullanarak jpsJVM PID var (benim durumumda 1) ve sonra ile jcmd 1 VM.flagsçalışan JVM bayrakları aldım.

Hangi komutlara sahip olduğunuza bağlıdır, ancak bu birine yardımcı olabilir. :)


8

Gönderen Java8 ve üzeri , komut aşağıda kullanabilirsiniz:

jcmd JAVA_PROCESS_IDGC.heap_info

Çıktıdan alınan toplam, kullanılan ve kullanılan belleğe başvurabilirsiniz.

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 komutu hakkında daha fazla bilgi için şu bağlantıyı ziyaret edin: https://docs.oracle.com/javase/8/docs/technotes/guides/troraseot/tooldescr006.html


1
Yorumunuzu düzeltmeniz gerekiyor. GC.heap_info, Java 9 ve üstü sürümlerde kullanılabilir. Java 8'de mevcut değildir. Buradaki başka bir konuya bakın: stackoverflow.com/questions/41891127/…
Pavel Molchanov

@PavelMolchanov Komutu jdk1.8.0_172'de kullanabiliyorum. /Library/Java/JavaVirtualMachines/jdk1.8.0_172.jdk/Contents/Home/bin/jcmd 98270 GC.heap_info. Eğer yapabilirseniz, yönlendirilen konuya bilgi ekleyin ve şu anda orada bir yorum eklemek için yeterli itibarım yok.
vaibhav gupta

Mac kullanıyor musunuz? Oracle JDK kullanıyor musunuz? Jdk1.8.0_172'nizde nasıl mevcut olabileceğini bilmiyorum, Oracle bu özelliği sadece Java 9 ve üstü için belgeledi : docs.oracle.com/javase/9/tools/jcmd.htm . Java 8 için Oracle JDK belgelerinde değildir. Altta verdiğiniz bağlantıda belirtilmemiş: docs.oracle.com/javase/8/docs/technotes/guides/troraseot/…
Pavel Molchanov

Bir soru daha. Lütfen örneğinizde 98270 işlemini çalıştıran JDK sürümünü kontrol edin. jcmd, işlemin JVM'sinden kullanılabilir komutları alır (sizin durumunuzda 98270). İşlem 98270 işlemi farklı JDK (JDK 9 veya üstü) ile yürütülürse, JCMD'de bile kullanılabilen GC.heap_info komutunun Java 8'den olduğunu görürsünüz. Kullanılabilir komutlar farklı işlemler için farklı olabilir. Kullanılabilir komutları almak için: jcmp <PID> yardım.
Pavel Molchanov

1
FWIW, GC.heap_infokesinlikle OpenJDK 8'de de mevcuttur. Belki sadece son sürümlerde? Bunu kullanıyorum: 8u191-b12-2ubuntu0.18.04.1
Per Lundberg

7

Herhangi bir yaklaşım size kabaca aynı sayı vermelidir. -X..m -X..xTüm nesiller için öbek ayırmak her zaman iyi bir fikirdir . Daha sonra hangi parametrelerin geçildiğini ve dolayısıyla kullanıldığını görmek için ps'yi garanti edebilir ve yapabilirsiniz.

Gerçek bellek kullanımları için, VIRT (ayrılmış ve paylaşılan) ve RES (gerçek kullanılan) karşılaştırmasını jstat değerleriyle de karşılaştırabilirsiniz:

Java 8 için, aslında bu değerler için jstat'a bakın . Mmap veya dosya işleme olmadan basit bir sınıf çalıştırdığınız varsayılarak.

$ 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

Maksimum :

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

(kabaca VIRT belleğe yakın ve aşağıda)

Maks (Min, Kullanılmış):

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

(kabaca RES belleğine yakın)

"Bana bu konuda alıntı yapma" ama VIRT mem kabaca ayrılan Max belleğe yakın veya daha fazladır, ancak kullanılan bellek fiziksel bellekte boş / kullanılabilir olduğu sürece , JVM bellek istisnası atmaz. Aslında, maksimum bellek, OS'de takas olsa bile JVM başlangıcında fiziksel belleğe karşı kontrol edilmez. Java işlemi tarafından gerçekten kullanılan Sanal belleğin daha iyi bir açıklaması burada ele alınmıştır .


4

İlk olarak, listelenen işlemin ilk numarası olan işlem kimliğini aşağıdakilerden birinden alın: (ya da ps aux | grep javaisterseniz bunu kullanın )

jps -lvm

Ardından işlem kimliğini burada kullanın:

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

2

topKomut kullanmak , programın bellek kullanımını kontrol etmenin en basit yoludur. RESsütunu, bir işlem tarafından kullanılan gerçek fiziksel belleği gösterir.

Benim durumum için, java bir 10g dosya vardı ve her defasında benOfMemory istisna var. Bu, RESsütundaki değer -Xmxseçeneğinde ayarlanan değere ulaştığında oldu . Sonra -Xmxseçeneği kullanarak belleği artırarak her şey yolunda gitti.


3
top komutu JVM'ye ne kadar işletim sistemi verildiğini gösterir. bu adamlar JVM içinde yığın alanı kullanımını nasıl görebileceğimizi soruyor. JVM 10g kullanmak, gerçek yığın alanının 10g veriyle dolu olduğu anlamına gelmez, çünkü jvm, işlemi öldürene kadar belleği asla OS'den geri döndürmez.
linehrr

2

Java yığın boyutu açısından, Linux'ta şunları kullanabilirsiniz:

ps aux | grep java

veya

ps -ef | grep java

ve belirtilen başlangıç ​​ve maksimum yığın boyutunu bulmak için -Xms, -Xmx öğelerini arayın.

Ancak, ilgilendiğiniz Java işlemi için -Xms veya -Xmx yoksa, Java işleminiz varsayılan yığın boyutlarını kullanıyor demektir. Varsayılan boyutları bulmak için aşağıdaki komutu kullanabilirsiniz.

java -XX:+PrintFlagsFinal -version | grep HeapSize

veya belirli bir jvm, örneğin,

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

ve bayt cinsinden InitialHeapSize ve MaxHeapSize öğelerini arayın.


1

Jrockit kullanıyorsanız jrcmd komut satırı aracını deneyin. Örneğin:

$ 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 gibi daha fazla komut için bunları listelemek üzere "jrcmd help" kullanın.

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 )

Yukarıdaki komutun örnek O / P'si

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

Bununla ilgili daha fazla bilgiyi http://docs.oracle.com/javase/1.5.0/docs/tooldocs/share/jstat.html adresinde bulabilirsiniz.


1

Yığın belleği istediğiniz gibi yazdırmak için şimdiye kadar böyle bir araç yoktur.Yazdırmanın tek ve tek yolu, Runtime Class'ın yardımıyla bir java programı yazmak ,

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);
}

}

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


Bu yanlış. jmap -heap <pid> bu bilgiyi verir
vsingh

0

Webapp / java işleminizin işlem kimliğini üstten bulun. Yığın tahsisini almak için jmap yığınını kullanın. Bunu AWS-Ec2'de elastik fasulye sapı için test ettim

Uygulama için maksimum 3GB'lık yığının altındaki resimde görebilirsiniz

resim açıklamasını buraya girin

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.