Windows上的Java堆栈跟踪

时间:2009-03-18 18:58:21

标签: java jstack

我需要获取在使用Windows的客户端计算机上运行的JVM进程的堆栈跟踪。

客户端安装了JRE但没有安装JDK。

我想使用JStack但它没有安装,我们无法在客户端的机器上安装JDK。我也尝试过使用来自Java Webstart会话的AdaptJ堆栈跟踪产品但由于我们远程进入并且因为不是在指定PID处启动应用程序的会话而出现错误而无效。

基本上我想要一种在不安装JDK的情况下安装JStack的方法。

6 个答案:

答案 0 :(得分:5)

您可能希望使用专为此目的而设计的SendSignal

答案 1 :(得分:4)

JDK和相关工具无论是否“安装”都可以正常工作,如果你只是压缩并将其解压缩到一个临时目录,你应该能够运行jstack。 (无需修改PATH或JAVA_HOME)。只需确保使用与客户端运行应用程序的JRE相对应的版本。至少在JConsole的情况下,如果版本不同,似乎大惊小怪。我不确定jstack的行为方式是否相同。

我不是说这是理想的解决方案,只是它会起作用。我认为jdigital和Eddie的建议是更好的第一个赌注,即使这不应该像运行安装程序一样干扰现有的java安装,客户也可能不同意。

答案 2 :(得分:2)

您是否可以通过远程访问使用JConsole

答案 3 :(得分:2)

jstack和jps是JDK的tools.jar的一部分。 还需要attach.dll将jstack附加到进程。

当然,tools.jar和attach.dll不是JRE的一部分。

为了让jstack在没有JDK的系统上工作(主要是Windows),我通常会这样做。

  1. 从JDK复制tools.jar和attach.dll并放入某个位置 在目标系统上。示例:到c:\ temp \ jstack
  2. 编写一个bat脚本,使用JRE手动调用它。
  3. 例如,创建一个bat文件jstack.bat:

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

    与jps类似,创建一个包含以下内容的jps.bat。

    设置JRE = c:\ jrefolder

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

    用法:

    jstack.bat -l <pid>
    

    希望这有帮助。

答案 4 :(得分:0)

要获得仅包含JRE的线程转储,您需要来自同一Java版本的JDK的tools.jar和attach.dll。在某处安装它并将它们复制到jre中。必须是完全相同的版本!

如果您需要转储在系统帐户下运行的进程,则可以使用Windows sysinternals psexec.exe来访问该进程。将其复制到JRE bin或路径中的某个位置。

此批处理文件将堆栈转储写入具有日期时间文件名的文件,因此可以轻松获取多个跟踪并进行比较。

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

答案 5 :(得分:0)

如果你想使用JDK的板载工具,并希望两者都有一个最小的(即不包括复制整个JDK)和方便(即不使用自定义.bat调用)解决方案,这对我有用(在Java 1.8上试过):

创建一个空文件夹(下面为$DEST)并将以下文件(从JDK $JDK_HOME)复制到binlib文件夹中,如下所示:

Source                          -> Destination

$JDK_HOME/bin/jps.exe           -> $DEST/bin/jps.exe
$JDK_HOME/bin/jstack.exe        -> $DEST/bin/jstack.exe
$JDK_HOME/bin/jli.dll           -> $DEST/bin/jli.dll
$JDK_HOME/jre/bin/attach.dll    -> $DEST/bin/attach.dll
$JDK_HOME/lib/tools.jar         -> $DEST/lib/tools.jar

然后ZIP并将其复制到运行兼容JRE的目标计算机上。

您现在可以从jps文件夹运行jstackbin,就像从原始JDK运行它们一样。