Windows 上的 Java 堆栈跟踪

发布于 2024-07-14 20:16:16 字数 261 浏览 9 评论 0原文

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

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

我想使用 JStack,但它尚未安装,并且我们无法在客户端计算机上安装 JDK。 我还尝试使用 Java Webstart 会话中的 AdaptJ 堆栈跟踪产品,但这不起作用,因为我们远程登录并收到错误,提示不是以指定 PID 启动应用程序的会话。

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

I need to get a stack trace for a JVM process running on a client machine that uses windows.

The client has the JRE installed but not the JDK.

I want to use JStack but it is not installed and we can't install a JDK on the client's machine. I also tried using AdaptJ stack trace product from a Java Webstart Session but that didn't work because we remote in and get an error about not being the session that started the application at a specified PID.

Essentially I want a way to install JStack without installing the JDK.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

七色彩虹 2024-07-21 20:16:16

您可能想使用 SendSignal,它正是为此目的而设计的。

You probably want to use SendSignal, which was designed for exactly this purpose.

策马西风 2024-07-21 20:16:16

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

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

The JDK and associated tools work fine whether "installed" or not, if you just zip up and extract it to a temporary directory, you should be able to run jstack. (No PATH or JAVA_HOME modifications necessary). Just make sure you use the same version that corresponds to the JRE your client has the application running with. At least in the case of JConsole, it seems to fuss if the versions are different. I'm not sure if jstack behaves the same way.

I'm not saying this is the ideal solution, just that it would work. I think jdigital and Eddie's suggestions are better first bets, and even though this shouldn't interfere with an existing java installation the same way running the installer would, the customer may disagree regardless.

允世 2024-07-21 20:16:16

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。

set 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>

希望这会有所帮助。

jstack and jps are part of tools.jar of the JDK.
Also attach.dll is required to attach jstack to a process.

Ofcourse the tools.jar and attach.dll are not part of JRE.

To make jstack work on a systems which has no JDK (mostly Windows), I usually do the following.

  1. Copy tools.jar and attach.dll from JDK and put in to some location
    on the target system. Example: to c:\temp\jstack
  2. Write a bat script to manually invoke it using JRE.

For example, create a bat file 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 %*

Similarly for jps, create a jps.bat with following content.

set JRE=c:\jrefolder

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

Usage:

jstack.bat -l <pid>

Hope this helps.

墨小沫ゞ 2024-07-21 20:16:16

您可以通过以下方式使用 JConsole远程访问?

Would you be able to use JConsole via remote access?

放低过去 2024-07-21 20:16:16

要仅使用 JRE 获取线程转储,您需要来自同一 Java 版本的 JDK 的 tools.jar 和 Attach.dll。 将其安装到某处并将它们复制到 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

To get a thread dump with only a JRE you need tools.jar and attach.dll from the JDK of the same Java version. Install this somewhere and copy these into the jre. Must be identical version!

If you need a dump of a process running under the system account you can use the Windows sysinternals psexec.exe to gain access to the process. Copy this into the JRE bin or somewhere in the path.

This batch file writes the stack dump to a file with a datetime filename so multiple traces can be taken and compared easily.

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
影子是时光的心 2024-07-21 20:16:16

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

创建一个空文件夹(下面的 $DEST)并将以下文件(从 JDK $JDK_HOME)复制到 < code>bin 和 lib 文件夹如下:

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 运行它们一样。

If you want to use the on-board tools of the JDK and also want to both have a minimal (i.e., not including copying the whole JDK) and convenient (i.e. not invoking with a custom .bat) solution, this works for me (tried on Java 1.8):

Create an empty folder ($DEST below) and copy the following files (from the JDK $JDK_HOME) into bin and lib folders as follows:

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

Then ZIP and copy this over to the destination machine running a compatible JRE.

You should be able to run jps and jstack from the bin folder now as you would run them from the original JDK.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文