Đang chạy jmap nhận được Không thể mở tệp socket


85

Tôi đã phải chạy jmapđể thực hiện đống đổ vỡ của quy trình của mình. nhưng jvmtrả lại:

Unable to open socket file: target process not responding or HotSpot VM not loaded
The -F option can be used when the target process is not responding

Vì vậy, tôi đã sử dụng -F:

./jmap -F -dump:format=b,file=heap.bin 10330
Attaching to process ID 10331, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 24.51-b03
Dumping heap to heap.bin ...
  1. Sử dụng -F có ổn không khi lấy heap dump?
  2. Tôi đang đợi 20 phút và vẫn chưa kết thúc. Bất kỳ ý tưởng tại sao?

Câu trả lời:


181

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.

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

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

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

  4. 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 euidegidcủ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).

  5. jmapkết nối với ổ cắm và gửi dumpheaplệnh.

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

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

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

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

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


84

Tôi chỉ thấy rằng jmap (và có lẽ là jvisualvm khi sử dụng nó để tạo một kết xuất đống) bắt buộc rằng người dùng đang chạy jmap phải là cùng một người dùng đang chạy quy trình cố gắng được kết xuất.

trong trường hợp của tôi, jvm mà tôi muốn có một kết xuất heap đang được chạy bởi người dùng linux "jboss". vì vậy nơi sudo jmap -dump:file.bin <pid>báo cáo "Không thể mở ổ cắm:", tôi có thể lấy kết xuất đống của mình bằng cách sử dụng:

sudo -u jboss jmap -dump:file.bin <pid>

Tôi nghĩ nó phải là \ -dump: file.bin <pid> vì bạn cần thoát khỏi - khi truyền tham số từ sudo vào jmap.
adam

Đây chính là nó! Bạn cũng cần sudo cho jmap và jcmd.
xtian

wow .. Điều này thực sự đã hoạt động. Điều này sẽ là câu trả lời được chấp nhận
Lalit Rao

3

Giống như ben_wing đã nói, bạn có thể chạy với:

sudo -u jboss-as jmap -dump:file.bin <pid>

(trong trường hợp của tôi là người dùng jboss-as, nhưng của bạn có thể là jbosshoặc một số khác.)

Nhưng vẫn chưa đủ, vì nó yêu cầu tôi nhập mật khẩu ( [sudo] password for ec2-user:), mặc dù tôi có thể chạy sudomà không cần nhắc tôi nhập mật khẩu bằng các lệnh khác.

Tôi đã tìm thấy giải pháp ở đây và tôi chỉ cần thêm một giải pháp khác sudotrước:

sudo sudo -u jboss-as jmap -dump:file.bin <pid>

Nó hoạt động với các lệnh khác như jcmdjinfoquá.


Nhân đôi sudotiết kiệm trong ngày của tôi!
Sher10ck

[root@v5 ~]# sudo sudo -u es jmap -dump:file=tmp.bin 26283 biến lỗi sudo: jmap: command not found. Tôi đã cấu hình đường dẫn java trong .bash_profile, tôi phải làm gì.
roamer

@roamer Có thể là do khi bạn chạy với tư cách esngười dùng, .bash_profilenó không được áp dụng (vì hồ sơ bash có liên quan đến người dùng của bạn, tôi cho là vậy). Tôi khuyên bạn nên bao gồm đường dẫn java theo cách toàn cục hơn hoặc có thể chỉ định đường dẫn java trong lệnh, như sudo sudo -u es PATH="$PATH:/java/path" jmap -dump:file=tmp.bin 26283( /java/pathđường dẫn java ở đâu và đảm bảo rằng nó có jmaptrong đó ).
Lucas Basquerotto

Tôi định cấu hình đường dẫn java trong /home/es/.bash_profile và tôi có thể sử dụng jmap khi đăng nhập với người dùng es. Cmd này sudo sudo -u es /usr/java/jdk1.8.0_181-cloudera/bin/jmap -dump:file=tmp.bin 26283hoạt động. Cảm ơn rất nhiều.
roamer

2

Nếu ứng dụng của bạn đang chạy dưới dạng dịch vụ systemd, bạn nên mở tệp dịch vụ dưới đó /usr/lib/systemd/system/và được đặt tên theo tên dịch vụ của bạn. Sau đó kiểm tra xem thuộc tính privateTmp có đúng không.

Nếu nó là true, bạn nên thay đổi nó thành false, sau đó làm mới dịch vụ bằng lệnh như sau: systemctl daemon-reload systemctl restart [servicename] Nếu bạn muốn chạy jmap / jcmd trước khi khởi động lại, bạn có thể sử dụng tập lệnh executeStop trong tệp dịch vụ. Chỉ cần đặt lệnh vào đó và thực thisystemctl stop [service name]


Trước khi tôi cập nhật /usr/lib/systemd/system/elasticsearch.service, đặt privateTmp thành false, tôi đã gặp lỗi này: Không thể mở tệp socket: tiến trình đích không phản hồi hoặc máy ảo HotSpot không được tải - mặc dù tôi đang chạy jmap dưới dạng người dùng tìm kiếm đàn hồi
imdibiji
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.