jmapso với jmap -F, cũng như jstackso với jstack -Fsử dụng các cơ chế hoàn toàn khác nhau để kết nối với JVM mục tiêu.
jmap / jstack
Khi chạy mà không có -Fcác công cụ này, hãy sử dụng Cơ chế Đính kèm Động . Điều này hoạt động như sau.
Trước khi kết nối với quy trình Java 1234, hãy jmaptạo một tệp .attach_pid1234tại thư mục làm việc của quy trình đích hoặc tại /tmp.
Sau đó jmapgửi SIGQUITđến tiến trình đích. Khi JVM bắt được tín hiệu và tìm thấy .attach_pid1234, nó sẽ bắt đầu AttachListenerluồng.
AttachListenerluồng tạo ổ cắm miền UNIX /tmp/.java_pid1234để nghe lệnh từ các công cụ bên ngoài.
Vì lý do bảo mật khi kết nối (từ jmap) được chấp nhận, JVM xác minh rằng thông tin xác thực của cổng ngang hàng ngang bằng euidvà egidcủa quy trình JVM. Đó là lý do tại sao jmapsẽ không hoạt động nếu được chạy bởi người dùng khác (thậm chí bởi root).
jmapkết nối với ổ cắm và gửi dumpheaplệnh.
Lệnh này được đọc và thực thi bởi AttachListenerluồng của JVM. Tất cả đầu ra được gửi trở lại ổ cắm. Vì kết xuất đống được thực hiện trong quy trình trực tiếp bởi JVM, hoạt động thực sự nhanh chóng. Tuy nhiên, JVM chỉ có thể làm điều này ở các điểm an toàn . Nếu không thể đạt được điểm an toàn (ví dụ: quá trình bị treo, không phản hồi hoặc đang thực hiện GC kéo dài), jmapsẽ hết thời gian chờ và không thành công.
Hãy tóm tắt những lợi ích và hạn chế của Dynamic Attach.
Ưu điểm.
- Kết xuất đống và các hoạt động khác được chạy cộng tác bởi JVM ở tốc độ tối đa.
- Bạn có thể sử dụng bất kỳ phiên bản nào của
jmaphoặc jstackđể kết nối với bất kỳ phiên bản JVM nào khác.
Nhược điểm
- Công cụ phải được chạy bởi cùng một người dùng (
euid/ egid) như JVM mục tiêu.
- Chỉ có thể được sử dụng trên JVM sống và khỏe mạnh.
- Sẽ không hoạt động nếu JVM mục tiêu được bắt đầu bằng
-XX:+DisableAttachMechanism.
jmap -F / jstack -F
Khi chạy với -Fcác công cụ, hãy chuyển sang chế độ đặc biệt có tính năng HotSpot Serviceability Agent . Trong chế độ này, quá trình đích bị đóng băng; các công cụ đọc bộ nhớ của nó thông qua các cơ sở gỡ lỗi hệ điều hành, cụ thể là ptracetrên Linux.
jmap -Fgọi PTRACE_ATTACHtrên JVM mục tiêu. Quá trình đích bị đình chỉ vô điều kiện theo SIGSTOPtín hiệu.
Công cụ đọc bộ nhớ JVM bằng cách sử dụng PTRACE_PEEKDATA. ptracechỉ có thể đọc một từ tại một thời điểm, do đó, cần có quá nhiều lệnh gọi để đọc đống lớn của quy trình đích. Điều này là rất và rất chậm.
Công cụ này tái tạo lại cấu trúc bên trong JVM dựa trên kiến thức về phiên bản JVM cụ thể. Vì các phiên bản khác nhau của JVM có cách bố trí bộ nhớ khác nhau, -Fchế độ chỉ hoạt động nếu jmapđến từ cùng một JDK với quy trình Java đích.
Công cụ này tự tạo kết xuất đống và sau đó tiếp tục quá trình đích.
Ưu điểm.
- Không cần sự hợp tác từ JVM mục tiêu. Có thể được sử dụng ngay cả trên một quá trình treo.
ptracehoạt động bất cứ khi nào đủ đặc quyền cấp hệ điều hành. Ví dụ: rootcó thể kết xuất quy trình của tất cả người dùng khác.
Nhược điểm
- Rất chậm đối với các đống lớn.
- Công cụ và quy trình đích phải từ cùng một phiên bản JDK.
- Điểm an toàn không được đảm bảo khi công cụ được gắn ở chế độ cưỡng bức. Mặc dù
jmapcố gắng xử lý tất cả các trường hợp đặc biệt, đôi khi có thể xảy ra trường hợp JVM mục tiêu không ở trạng thái nhất quán.
Ghi chú
Có một cách nhanh hơn để lấy đống đổ ở chế độ bắt buộc. Đầu tiên, tạo một coredump gcore, sau đó chạy jmaptrên tệp lõi đã tạo. Xem câu hỏi liên quan .