Làm thế nào để theo dõi một chương trình java?


25

Là một sysadmin đôi khi tôi phải đối mặt với các tình huống, trong đó một chương trình hoạt động bất thường, trong khi không tạo ra lỗi nào cả hoặc tạo ra các thông báo lỗi vô nghĩa.

Trong quá khứ - trước khi java xuất hiện - có hai biện pháp đối phó:

  1. Nếu không có gì khác giúp - RTFM ;-)
  2. Nếu thậm chí 1. không giúp - theo dõi các cuộc gọi hệ thống và xem điều gì đang xảy ra

Tôi thường sử dụng strace -fcho nhiệm vụ này với Linux (hệ điều hành khác có các công cụ theo dõi tương tự). Bây giờ trong khi điều này thường hoạt động tốt cho bất kỳ chương trình lỗi thời nào, dấu vết sẽ rất mờ khi thực hiện tương tự trên một quy trình java . Có rất nhiều cuộc gọi hệ thống dường như không liên quan đến bất kỳ hành động thực tế nào, thật tệ khi tìm kiếm thông qua một bãi rác như vậy.

Có cách nào tốt hơn để làm điều đó (nếu mã nguồn không có sẵn)?

Câu trả lời:


16

Như ckhan đã đề cập, jstackthật tuyệt vời vì nó cung cấp dấu vết ngăn xếp đầy đủ của tất cả các luồng hoạt động trong JVM. Điều tương tự có thể thu được trên thiết bị lỗi chuẩn của JVM bằng SIGQUIT.

Một công cụ hữu ích khác là jmapcó thể lấy một đống heap từ quy trình JVM bằng cách sử dụng PID của quy trình:

jmap -dump:file=/tmp/heap.hprof $PID

Heap dump này có thể được tải trong các công cụ như visualvm(hiện là một phần của bản cài đặt java java java tiêu chuẩn, có tên là jvisualvm). Ngoài ra, VisualVM có thể kết nối với JVM đang chạy và hiển thị thông tin về JVM, bao gồm hiển thị biểu đồ sử dụng CPU bên trong, số lượng luồng và sử dụng heap - tuyệt vời để theo dõi rò rỉ.

Một công cụ khác jstat, có thể thu thập số liệu thống kê thu gom rác cho JVM trong một khoảng thời gian giống như vmstat khi chạy với một đối số số (ví dụ vmstat 3).

Cuối cùng, có thể sử dụng Tác nhân Java để đẩy thiết bị trên tất cả các phương thức của tất cả các đối tượng tại thời điểm tải. Thư viện javassistcó thể giúp thực hiện điều này rất dễ dàng để làm. Vì vậy, nó là khả thi để thêm dấu vết của riêng bạn. Phần khó với điều đó sẽ là tìm cách để có được đầu ra theo dõi chỉ khi bạn muốn và không phải lúc nào cũng có thể làm chậm JVM để thu thập dữ liệu. Có một chương trình được gọi là dtracehoạt động theo cách như thế này. Tôi đã thử nó, nhưng không thành công lắm. Lưu ý rằng các tác nhân không thể tạo thành công cụ cho tất cả các lớp vì các lớp cần thiết để khởi động JVM được tải trước khi tác nhân có thể tạo thành công cụ, và sau đó đã quá muộn để thêm thiết bị vào các lớp đó.

Đề xuất của tôi - bắt đầu với VisualVM và xem nếu điều đó cho bạn biết những gì bạn cần biết vì nó có thể hiển thị các luồng hiện tại và các số liệu thống kê quan trọng cho JVM.


Nhân tiện, đây là một câu hỏi tuyệt vời; Tôi hy vọng nhiều người thêm câu trả lời với các ý tưởng khác. Khi tôi hỏi những người làm việc với Java trong nhiều năm về việc truy tìm, họ đã cho tôi những cái nhìn trống rỗng. Có lẽ họ chỉ không biết sự tuyệt vời của bước đi.
tro

10

Tương tự như vậy khi gỡ lỗi các chương trình đã bị lỗi trên hệ thống Linux, bạn có thể sử dụng các công cụ tương tự để gỡ lỗi chạy JVM trên hệ thống của mình.

Công cụ # 1 - jvmtop

Tương tự như vậy top, bạn có thể sử dụng jvmtop để xem các lớp nào đang hoạt động trong các JVM đang chạy trên hệ thống của bạn. Sau khi cài đặt, bạn gọi nó như thế này:

$ jvmtop.sh

Đầu ra của nó có kiểu dáng tương tự như công cụ top:

 JvmTop 0.8.0 alpha   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

Công cụ # 2 - jvmmonitor

Một cách khác là sử dụng jvmmonitor . JVM Monitor là một trình lược tả Java được tích hợp với Eclipse để giám sát việc sử dụng CPU, luồng và bộ nhớ của các ứng dụng Java. Bạn có thể sử dụng nó để tự động tìm các JVM đang chạy trên localhost hoặc nó có thể kết nối với các JVM từ xa bằng cách sử dụng cổng @ host.

ss của jvmmonitor

Công cụ # 3 - visualvm

visualvm có lẽ là "công cụ" để tiếp cận khi gỡ lỗi các vấn đề với JVM. Bộ tính năng của nó khá sâu và bạn có thể có một cái nhìn rất sâu sắc về các bộ phận bên trong.

Hiệu suất ứng dụng hồ sơ hoặc phân tích phân bổ bộ nhớ:

ss của visualvm # 2

Lấy và hiển thị các bãi chứa chủ đề:

ss của visualvm # 3

Tài liệu tham khảo


4

Hãy xem xét jstack. Không hoàn toàn phù hợp với strace, nhiều hơn một pstack-analog, nhưng ít nhất sẽ cung cấp cho bạn một hình ảnh chụp nhanh theo thời gian. Có thể xâu chuỗi lại với nhau để có được một dấu vết thô nếu bạn phải.

Xem thêm các đề xuất tại bài viết SO này: /programming/1025681/call-trace-in-java


2

Nếu bạn đang sử dụng RHEL OpenJDK (hoặc tương tự, vấn đề là đó không phải là JDK của Oracle), bạn có thể sử dụng SystemTap cho điều đó.

Một số đầu dò được kích hoạt bằng cách sử dụng tùy chọn dòng lệnh java -XX:+DTraceMethodProbes, -XX:+DTraceAllocProbes, -XX:+DTraceMonitorProbes. Lưu ý rằng việc kích hoạt các đầu dò này sẽ ảnh hưởng đáng kể đến hiệu suất chương trình.

Dưới đây là ví dụ về SystemTap Script:

#!/usr/bin/stap

probe hotspot.class_loaded {
    printf("%12s [???] %s\n", name, class);
}

probe hotspot.method_entry, 
      hotspot.method_return {
    printf("%12s [%3d] %s.%s\n", name, thread_id, class, method);
}

probe hotspot.thread_start, 
      hotspot.thread_stop {
    printf("%12s [%3d] %s\n", name, id, thread_name);
}

probe hotspot.monitor_contended_enter, 
      hotspot.monitor_contended_exit {
    printf("%12s [%3d] %s\n", name, thread_id, class);
}

Bạn cũng có thể sử dụng jstack()để lấy ngăn xếp Java của quá trình, nhưng nó sẽ chỉ hoạt động nếu bạn khởi động SystemTap trước JVM.


Lưu ý rằng SystemTap sẽ theo dõi mọi phương thức. Nó cũng không thể có được các đối số của phương thức. Một tùy chọn khác là sử dụng các khả năng truy tìm của JVM, được gọi là JVMTI. Một trong những triển khai JVMTI nổi tiếng nhất là BTrace .


0

Bạn nên dùng thử Jackplay , đây là một công cụ theo dõi JVM cho phép bạn theo dõi mục nhập và thoát phương thức mà không cần thay đổi mã hoặc triển khai lại.


Bạn không thể đính kèm nó vào một JVM đang chạy. Ngoài ra - công cụ thú vị
Nils
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.