2009-03-18 40 views
5

Tôi cần có một dấu vết ngăn xếp cho một quá trình JVM chạy trên máy khách sử dụng các cửa sổ.Theo dõi ngăn xếp Java trên Windows

Máy khách đã cài đặt JRE chứ không phải JDK.

Tôi muốn sử dụng JStack nhưng chưa được cài đặt và chúng tôi không thể cài đặt JDK trên máy của khách hàng. Tôi cũng đã thử sử dụng sản phẩm theo dõi stack của AdaptJ từ một phiên Webstart của Java nhưng điều đó không làm việc vì chúng ta đã từ xa và nhận được một lỗi về việc không phải là phiên khởi động ứng dụng tại một PID xác định.

Về cơ bản tôi muốn có cách cài đặt JStack mà không cần cài đặt JDK.

+3

Chỉ cần để tham khảo, "giết -3 pid" sẽ gây ra một Unix/Linux jre để đổ toàn bộ thread stack trace tới stdout. Rất, rất, rất tiện dụng. –

Trả lời

5

Bạn có thể muốn sử dụng SendSignal, được thiết kế cho mục đích chính xác này.

+0

Từ khi nhìn vào trang web SendSignal, tôi sẽ cẩn thận nếu ứng dụng đang được chạy dưới dạng dịch vụ (hoặc có các -Xrs (giảm sử dụng tín hiệu)) làm đối số. Nếu vậy, thao tác xử lý ngắt + ctrl của Java bị tắt và ứng dụng sẽ chấm dứt khi nhận được tín hiệu này. –

+0

Trên thực tế, tôi sử dụng SendSignal.exe cho mục đích này để gây ra stackdump của một JRE chạy như một dịch vụ. Nó làm việc cho tôi. – Eddie

+0

Có, nếu ai đó chạy "java -Xrs ..." thì có lẽ họ sẽ gặp sự cố với SendSignal.exe. Giải pháp là bạn không thể làm cả hai cùng một lúc. Chọn một. Hoặc sử dụng -Xrs hoặc sử dụng SendSignal.exe để gây ra một stackdump. Lựa chọn của bạn. – Eddie

2

Bạn có thể sử dụng JConsole thông qua truy cập từ xa không?

+0

+1 jvisualvm cũng tiện dụng –

4

JDK và các công cụ liên quan hoạt động tốt dù được "cài đặt" hay không, nếu bạn chỉ nén và giải nén nó vào một thư mục tạm thời, bạn sẽ có thể chạy jstack. (Không cần sửa đổi PATH hoặc JAVA_HOME). Chỉ cần đảm bảo bạn sử dụng cùng một phiên bản tương ứng với JRE mà ứng dụng của bạn có ứng dụng đang chạy cùng. Ít nhất trong trường hợp của JConsole, có vẻ như phiền phức nếu các phiên bản khác nhau. Tôi không chắc chắn nếu jstack cư xử theo cùng một cách.

Tôi không nói đây là giải pháp lý tưởng, chỉ là nó sẽ hoạt động. Tôi nghĩ rằng các đề xuất của jdigital và Eddie là cược đầu tiên tốt hơn, và mặc dù điều này không ảnh hưởng đến cài đặt java hiện có giống như cách chạy trình cài đặt, khách hàng có thể không đồng ý bất kể.

2

jstack và jps là một phần của tools.jar của JDK. Ngoài ra attach.dll là cần thiết để đính kèm jstack vào một quá trình.

Ofcourse tools.jar và attach.dll không phải là một phần của JRE.

Để thực hiện công việc jstack trên một hệ thống không có JDK (chủ yếu là Windows), tôi thường làm như sau.

  1. Sao chép tools.jar và attach.dll từ JDK và đặt vào một số vị trí trên hệ thống đích. Ví dụ: để c: \ temp \ jstack
  2. Viết kịch bản dơi để gọi thủ công bằng cách sử dụng JRE.

Ví dụ, tạo một jstack.bat file bat:

set JRE=c:\jrefolder 
"%JRE%\bin\java" -classpath "c:\temp\jstack\tools.jar" -Djava.library.path="c:\temp\jstack" sun.tools.jstack.JStack %* 

Tương tự như vậy cho JPS, tạo một jps.bat với nội dung sau đây.

bộ JRE = c: \ jrefolder

"%JRE%\bin\java" -classpath "c:\temp\jstack\tools.jar" -Djava.library.path="c:\temp\jstack" sun.tools.jps.Jps %* 

Cách sử dụng:

jstack.bat -l <pid> 

Hope this helps.

+0

jps hoạt động tốt theo cách này, nhưng jstack không thành công với "java.util.ServiceConfigurationError: com.sun.tools.attach.spi.AttachProvider: Nhà cung cấp sun.tools.attach.WindowsAttachProvider không thể được khởi tạo" –

+0

@EmmanuelBourg Bạn có chắc chắn rằng attach.dll hiện diện trong đường dẫn được đề cập trong -Djava.library.path =? Làm ơn xác thực. attach.dll là cần thiết để đính kèm quá trình để jstack. –

+0

Có, nhưng tôi đã cố gắng đính kèm vào một tiến trình đang chạy với tư cách Quản trị viên và vỏ của tôi không có đặc quyền nâng cao, điều đó có thể giải thích được vấn đề. –

0

Để tải một chuỗi chỉ với một JRE, bạn cần tools.jar và attach.dll từ JDK của cùng một phiên bản Java. Cài đặt nơi này và sao chép chúng vào jre. Phải là phiên bản giống hệt nhau!

Nếu bạn cần một kết xuất của một tiến trình đang chạy trong tài khoản hệ thống, bạn có thể sử dụng Windows sysinternals psexec.exe để truy cập vào quy trình. Sao chép dữ liệu này vào thùng JRE hoặc một nơi nào đó trong đường dẫn.

Tệp lô này ghi kết xuất ngăn xếp vào một tệp có tên tệp ngày giờ để có thể thực hiện và so sánh nhiều dấu vết dễ dàng.

Threads.bat

:: Creates a thread dump for the tomcat6.exe process 
:: saved in a timestamped filename and views it! 
:: Jim Birch 20111128 rev 2015-10-12 

::Required the following files to be placed in the jre/bin folder: 
:: attach.dll - From the Java JDK (must be the same version) 
:: tools.jar - ditto 
:: psexec.exe - from Windows sysinternals 

::cd to jre/bin 
d: 
cd \application\jre\bin 

::build datetime filename 
rem datetime from wmi.exe 
for /f "tokens=2 delims==" %%I in ('wmic os get localdatetime /format:list') do set dt0=%%I 
rem datetime string as YYYY-MM-DD-hhmmss 
set dt=%dt0:~0,4%-%dt0:~4,2%-%dt0:~6,2%-%dt0:~8,6% 
set ff=td-%dt%.txt 
echo filename: %ff% 

::PID of the process by named exe, eg, tomcat6  
for /F "tokens=2" %%I in ('TASKLIST /NH /FI "IMAGENAME eq tomcat6.exe"') DO SET PID=%%I 
echo pid: %PID% 

::combine above with jstack command 
psexec -s jstack.exe -l %PID% >> %ff% 

:: view result 
start %ff% 

::insert pause to debug or timer to review script operation 
::ping localhost -n 20 >nul 
::pause 
Các vấn đề liên quan