繁体   English   中英

Java 堆栈跟踪 Windows

[英]Java stack trace on Windows

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

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

我想使用 JStack,但它没有安装,我们无法在客户端机器上安装 JDK。 我还尝试使用来自 Java Webstart Session 的 AdaptJ 堆栈跟踪产品,但这不起作用,因为我们远程进入并收到一个错误,即不是 Z21D6F40CFB511982E4424E0E250A95 指定的应用程序启动的应用程序。

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

您可能想要使用专为此目的而设计的SendSignal

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

我并不是说这是理想的解决方案,只是它会起作用。 我认为 jdigital 和 Eddie 的建议是更好的首选,即使这不会像运行安装程序那样干扰现有的 java 安装,但客户可能不同意。

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 手动调用它。

例如,创建一个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>

希望这可以帮助。

您可以通过远程访问使用JConsole吗?

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

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

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

线程.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

如果您想使用 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 的目标计算机。

您现在应该能够从bin文件夹中运行jpsjstack ,就像从原始 JDK 中运行它们一样。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM