Công cụ dòng lệnh để tìm kích thước và bộ nhớ heap Java được sử dụng (Linux)?


171

Có Công cụ dòng lệnh (Linux) để kiểm tra Kích thước heap (và Bộ nhớ đã sử dụng) của Ứng dụng Java không?

Tôi đã thử qua jmap. Nhưng nó cung cấp thông tin. về các vùng bộ nhớ trong như Eden / PermGen, v.v., không hữu ích với tôi.

Tôi đang tìm kiếm một cái gì đó như:

  • Bộ nhớ tối đa: 1GB
  • Bộ nhớ tối thiểu: 256 MB
  • Bộ nhớ heap: 700 MB
  • Bộ nhớ đã sử dụng: 460 MB

Đó là tất cả. Tôi biết rằng tôi có thể thấy điều này trong JConsole, v.v., nhưng tôi cần một công cụ dòng lệnh (không thể kích hoạt JMX, v.v.)

Bạn có biết một công cụ / lệnh như vậy không?

Câu trả lời:


149

Mỗi quy trình Java có một pid, mà trước tiên bạn cần tìm bằng jpslệnh.

Một khi bạn có pid, bạn có thể sử dụng jstat -gc [insert-pid-here]để tìm số liệu thống kê về hành vi của đống rác được thu thập.

  • jstat -gccapacity [insert-pid-here] sẽ trình bày thông tin về khả năng tạo bộ nhớ và khả năng không gian.

  • jstat -gcutil [insert-pid-here]sẽ trình bày việc sử dụng mỗi thế hệ theo phần trăm công suất của nó. Hữu ích để có được một cái nhìn thoáng qua về việc sử dụng.

Xem tài liệu jstat trên trang web của Oracle.


11
Có khuyến nghị nào về các tùy chọn của jstatmột người nên sử dụng để xác minh chỉ sử dụng bộ nhớ chung của JVM không? Giả sử bạn khởi động JVM với Xms=4gXmx=4gbạn muốn xem, bao nhiêu bộ nhớ đã được sử dụng?
basZero

1
"Jstat -gcutil <pid> 250 N" rất hữu ích để lấy N mẫu với các khoảng 250ms và hiển thị đầu ra dưới dạng phần trăm cho các khoảng trắng tương ứng. Cảm ơn.
Kerem

3
Trích dẫn đáng chú ý từ trangjstat hướng dẫn Oracle Java 8 : . This command is experimental and unsupported
patryk.beza

1
awk 'print {$3+$4+$6+$8}'có thể in sử dụng tóm tắt trên các cột jstat của Java 8
cybersoft

Có vấn đề với các câu trả lời khác, nhưng một cơ bản ps -ef | grep javađã cho tôi thấy vm args, trong trường hợp của tôi bao gồm giá trị -Xmx, đó là tất cả những gì tôi cần.
xdhmoore

66

jvmtop là một công cụ dòng lệnh cung cấp chế độ xem trực tiếp ở một số số liệu, bao gồm cả heap.

Ví dụ đầu ra của chế độ tổng quan 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

Nó thực sự là một công cụ tuyệt vời, loại htop nhưng với số liệu từ jstat. Cảm ơn đề xuất, @MRalwasser.
oski86

65

Lệnh này hiển thị kích thước heap được cấu hình theo byte.

java -XX:+PrintFlagsFinal -version | grep HeapSize

Nó cũng hoạt động trên Amazon AMI trên EC2.


26
Điều này không trả lời câu hỏi, mà cụ thể là hỏi cách kiểm tra việc sử dụng đống của một quy trình. Lệnh ở đây liệt kê các mặc định JVM trên tất cả các quy trình.
Madbreaks

10
Tuy nhiên, đây là một câu trả lời rất hữu ích cho tôi khi đến trang này thông qua tìm kiếm của google về cách tìm kích thước heap toàn cầu.
Johan

@jumping_monkey không gián tiếp, không chính xác. Nếu điều bạn nói là đúng, câu trả lời sẽ được chỉnh sửa hoặc bạn nên thoải mái thêm câu trả lời mới.
Đột phá

42

Hãy thử nó hoạt động trong Ubuntu và RedHat:

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

Cho cửa sổ:

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

Dành cho máy Mac

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

Đầu ra của tất cả các lệnh này giống với đầu ra bên dưới:

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)

Để tìm kích thước tính bằng MB, chia giá trị cho (1024 * 1024).


Làm cách nào để tìm cách sử dụng bộ nhớ được phân tách bằng heap, permsize, ... của quá trình java cụ thể bằng pid?
Gary Gauh

3
@GaryGauh Đây là kích thước heap mặc định. Để tìm cách sử dụng ứng dụng đang chạy, bạn nên thực hiện trong mã hoặc bạn có thể sử dụng jconsole. Đây là những gì tôi biết cũng nên có nhiều cách khác.
padippist

2
Sử dụng jstat -gc <vmid>để chạy các ứng dụng.
Micha Wiedenmann

27

Không sử dụng JMX, đó là những gì hầu hết các công cụ sử dụng, tất cả những gì bạn có thể làm là sử dụng

jps -lvm

và suy ra rằng các cài đặt sẽ từ các tùy chọn dòng lệnh.

Bạn không thể nhận thông tin động mà không có JMX theo mặc định nhưng bạn có thể viết dịch vụ của riêng mình để thực hiện việc này.

BTW: Tôi thích sử dụng VisualVM hơn là JConsole.


25

Có một công cụ dòng lệnh với khía cạnh trực quan - jvm-mon . Nó là một công cụ giám sát JVM cho dòng lệnh không chấp nhận:

  • sử dụng heap, kích thước và tối đa
  • quy trình jvm
  • sử dụng cpu và GC
  • chủ đề hàng đầu

Các số liệu và biểu đồ cập nhật trong khi công cụ đang mở.

Mẫu vật: jvm-mon


1
Chỉ cần lưu ý rằng jvm-mon chỉ chạy cho Java8
tmanolatos

1
^ Có một phiên bản mới hiện cũng hỗ trợ Java 11.
Andrejs

11

Đi tiệc muộn, nhưng một giải pháp rất đơn giản là sử dụng tập lệnh jpsstat.sh. Nó cung cấp một bộ nhớ hiện tại trực tiếp đơn giản , bộ nhớ tối đa và chi tiết sử dụng cpu .

  • Dự án Goto GitHub và tải xuống tệp jpsstat.sh
  • Nhấp chuột phải vào jpsstat.sh và goto quyền tab và làm cho nó thực thi
  • Bây giờ Chạy tập lệnh bằng lệnh sau ./jpsstat.sh

Đây là đầu ra mẫu của tập lệnh -

=====  ======  =======  =======  =====
 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

dường như không hoạt động tốt trên SUSE Linux (dòng 38: khai báo: -A: tùy chọn không hợp lệ)
Chris

có vẻ như bạn gặp lỗi trong khai báo mảng kết hợp cần bash> = 4. Ngoài ra, một vấn đề khác có thể là do chạy tập lệnh là "sh jpsstat.sh". Nếu vậy, hãy thử chạy tập lệnh dưới dạng "./jpsstat.sh".
amarjeetAnand

9

Trong trường hợp của tôi, tôi cần kiểm tra các cờ bên trong thùng chứa docker không có hầu hết các tiện ích cơ bản (ps, pstree ...)

Sử dụng jpstôi đã nhận được PID của JVM đang chạy (trong trường hợp 1 của tôi) và sau đó jcmd 1 VM.flagstôi nhận được các cờ từ JVM đang chạy.

Nó phụ thuộc vào những lệnh bạn có sẵn, nhưng điều này có thể giúp ai đó. :)


8

Từ Java8 trở lên , bạn có thể sử dụng lệnh bên dưới:

jcmd JAVA_PROCESS_IDGC.heap_info

Bạn có thể tham khảo tổng, bộ nhớ và bộ nhớ đã sử dụng từ đầu ra.

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

Để biết thêm chi tiết về lệnh jcmd, hãy truy cập liên kết: https://docs.oracle.com/javase/8/docs/technotes/guides/troubledhoot/tooldescr006.html


1
Bạn cần phải sửa bình luận của bạn. GC.heap_info có sẵn trong Java 9 trở lên. Nó không có sẵn trong Java 8. Xem một chủ đề khác ở đây: stackoverflow.com/questions/41891127/ triệt
Pavel Molchanov

@PavelMolchanov Tôi có thể sử dụng lệnh trong jdk1.8.0_172. / L Library / Java / JavaVirtualMachines / jdk1.8.0_172.jdk / Content / Home / bin / jcmd 98270 GC.heap_info. Xin vui lòng nếu bạn có thể, Thêm thông tin vào chủ đề được giới thiệu cũng như tôi không có đủ danh tiếng như bây giờ để thêm một nhận xét ở đó.
vaibhav gupta

Bạn có sử dụng máy Mac không? Bạn có sử dụng Oracle JDK không? Tôi không biết làm thế nào nó có thể có sẵn trong jdk1.8.0_172 của bạn, Oracle chỉ ghi lại tính năng này trong Java 9 trở lên: docs.oracle.com/javase/9/tools/jcmd.htm . Nó không có trong tài liệu Oracle JDK cho Java 8. Nó không được đề cập trong liên kết mà bạn đã đưa ra ở dưới cùng: docs.oracle.com/javase/8/docs/technotes/guides/troubledhoot/ trộm
Pavel Molchanov

Thêm một câu hỏi nữa. Vui lòng kiểm tra phiên bản JDK đang chạy tiến trình 98270 trong ví dụ của bạn. jcmd nhận các lệnh có sẵn từ JVM của quá trình (trong trường hợp của bạn là 98270). Nếu quy trình 98270 được thực thi với JDK khác nhau (JDK 9 trở lên), bạn sẽ thấy lệnh GC.heap_info có sẵn ngay cả trong chính JCMD là từ Java 8. Các lệnh có sẵn có thể khác nhau cho các quy trình khác nhau. Để nhận các lệnh khả dụng, hãy thực hiện: trợ giúp jcmp <PID>.
Pavel Molchanov

1
FWIW, GC.heap_infochắc chắn cũng có sẵn trong OpenJDK 8. Có lẽ chỉ trong các phiên bản gần đây? Tôi đang sử dụng cái này: 8u191-b12-2ubfox0.18.04.1
Per Lundberg

7

Bất kỳ cách tiếp cận sẽ cung cấp cho bạn số lượng gần như nhau. Luôn luôn là một ý tưởng tốt để phân bổ heap sử dụng -X..m -X..xcho tất cả các thế hệ. Sau đó, bạn có thể đảm bảo và cũng làm ps để xem tham số nào đã được thông qua và do đó được sử dụng.

Đối với việc sử dụng bộ nhớ thực tế, bạn có thể so sánh đại khái VIRT (được phân bổ và chia sẻ) và RES (được sử dụng thực tế) so với các giá trị jstat:

Đối với Java 8, hãy xem jstat cho các giá trị này thực sự có nghĩa. Giả sử bạn chạy một lớp đơn giản không có mmap hoặc xử lý tệp.

$ 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

Tối đa :

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

(gần và bên dưới bộ nhớ VIRT)

Tối đa (Tối thiểu, Được sử dụng):

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

(gần với bộ nhớ RES)

"Đừng trích dẫn tôi về điều này" nhưng mem VIRT gần bằng hoặc nhiều hơn bộ nhớ Max được phân bổ nhưng miễn là bộ nhớ được sử dụng là miễn phí / có sẵn trong bộ nhớ vật lý, JVM không ném ngoại lệ bộ nhớ. Trong thực tế, bộ nhớ tối đa thậm chí không được kiểm tra đối với bộ nhớ vật lý khi khởi động JVM ngay cả khi hoán đổi trên HĐH. Một lời giải thích tốt hơn về những gì bộ nhớ ảo thực sự được sử dụng bởi một quy trình Java sẽ được thảo luận ở đây .


4

Trước tiên hãy lấy id quy trình, số đầu tiên từ quy trình được liệt kê, từ một trong các cách sau: (hoặc chỉ sử dụng ps aux | grep java, nếu bạn thích điều đó)

jps -lvm

Sau đó sử dụng ID tiến trình tại đây:

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

2

Sử dụng toplệnh là cách đơn giản nhất để kiểm tra việc sử dụng bộ nhớ của chương trình. REScột hiển thị bộ nhớ vật lý thực sự bị chiếm bởi một quá trình.

Đối với trường hợp của tôi, tôi đã có một tệp 10g được đọc bằng java và mỗi lần tôi nhận được ngoại lệOfMemory. Điều này xảy ra khi giá trị trong REScột đạt đến giá trị được đặt trong -Xmxtùy chọn. Sau đó, bằng cách tăng bộ nhớ bằng cách sử dụng -Xmxtùy chọn, mọi thứ đều ổn.


3
lệnh trên cùng đang hiển thị bao nhiêu hệ điều hành được trao cho JVM. những người này đang hỏi làm thế nào chúng ta có thể thấy việc sử dụng không gian đống trong JVM. JVM đang sử dụng 10g không có nghĩa là không gian heap thực sự chứa đầy 10g dữ liệu, vì jvm gần như không bao giờ trả lại bộ nhớ cho OS từ heap cho đến khi bạn giết tiến trình.
linehrr

2

Về kích thước heap Java, trong Linux, bạn có thể sử dụng

ps aux | grep java

hoặc là

ps -ef | grep java

và tìm -Xms, -Xmx để tìm kích thước heap ban đầu và tối đa được chỉ định.

Tuy nhiên, nếu -Xms hoặc -Xmx không có trong quy trình Java mà bạn quan tâm, điều đó có nghĩa là quy trình Java của bạn đang sử dụng các kích thước heap mặc định. Bạn có thể sử dụng lệnh sau để tìm ra kích thước mặc định.

java -XX:+PrintFlagsFinal -version | grep HeapSize

hoặc một jvm cụ thể, ví dụ,

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

và tìm kiếm FirstHeapSize và MaxHeapSize, tính bằng byte.


1

Nếu sử dụng jrockit hãy thử công cụ dòng lệnh jrcmd. Ví dụ:

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

Để biết thêm các lệnh, như heap_diagnostics, hãy sử dụng "trợ giúp jrcmd" để liệt kê chúng.

https://bloss.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 )

Mẫu O / P của lệnh trên

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

Nhận thêm thông tin chi tiết về điều này tại http://docs.oracle.com/javase/1.5.0/docs/tooldocs/share/jstat.html


1

Cho đến nay, không có công cụ nào như vậy để in bộ nhớ heap theo định dạng như bạn yêu cầu Cách duy nhất và duy nhất để in là viết chương trình java với sự trợ giúp của Runtime Class ,

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

}

tham khảo: https://viruspatel.net/bloss/getting-jvm-heap-size-use-memory-total-memory-USE-java-r nb /


cái này sai. jmap -heap <pid> cung cấp thông tin này
vsingh

0

Tìm id tiến trình của quy trình webapp / java của bạn từ đầu. Sử dụng heap jmap để có được phân bổ heap. Tôi đã thử nghiệm điều này trên AWS-Ec2 cho cây đậu đàn hồi

Bạn có thể thấy trong hình dưới heap tối đa 3 GB cho ứng dụng

nhập mô tả hình ảnh ở đây

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.