jmap
so với jmap -F
, cũng như jstack
so với jstack -F
sử 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ó -F
cá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 jmap
tạo một tệp .attach_pid1234
tại thư mục làm việc của quy trình đích hoặc tại /tmp
.
Sau đó jmap
gử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 AttachListener
luồng.
AttachListener
luồ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 euid
và egid
của quy trình JVM. Đó là lý do tại sao jmap
sẽ không hoạt động nếu được chạy bởi người dùng khác (thậm chí bởi root).
jmap
kết nối với ổ cắm và gửi dumpheap
lệnh.
Lệnh này được đọc và thực thi bởi AttachListener
luồ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), jmap
sẽ 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
jmap
hoặ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 -F
cá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à ptrace
trên Linux.
jmap -F
gọi PTRACE_ATTACH
trên JVM mục tiêu. Quá trình đích bị đình chỉ vô điều kiện theo SIGSTOP
tín hiệu.
Công cụ đọc bộ nhớ JVM bằng cách sử dụng PTRACE_PEEKDATA
. ptrace
chỉ 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, -F
chế độ 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.
ptrace
hoạt động bất cứ khi nào đủ đặc quyền cấp hệ điều hành. Ví dụ: root
có 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ù
jmap
cố 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 jmap
trên tệp lõi đã tạo. Xem câu hỏi liên quan .