我可以让 Tomcat 作为服务运行以转储堆吗?

Posted

技术标签:

【中文标题】我可以让 Tomcat 作为服务运行以转储堆吗?【英文标题】:Can I get Tomcat running as a service to dump heap? 【发布时间】:2011-01-11 10:45:30 【问题描述】:

我正在尝试让当前在 Windows 2003 机器上作为服务运行的 Tomcat 将堆转储到 OutOfMemoryError

(Tomcat 正在运行 Hudson,它在我的构建结束时报告堆空间问题。手动运行构建不会产生此类错误。Hudson 的人需要堆转储才能开始。)

按照其他地方的说明,我已经告诉 Apache Service Monitor 配置它用来运行 Tomcat 的 JVM,以便在遇到 OutOfMemoryError 时通过将以下内容添加到 JVM 选项来转储堆: -XX:+HeapDumpOnOutOfMemoryError 然后我再次运行构建。果然,它报告了一个堆错误。我扫描整个磁盘以寻找默认的java_pid123.hprof 文件(显然123 被JVM 的PID 替换)。任何地方都不存在.hprof 文件。

我陷入了第 22 个问题:我需要 Hudson 的人的堆转储来修复他们的内存泄漏,但如果我在 Tomcat 下运行 Hudson,我无法获得堆转储。

当 Tomcat 作为 Windows 服务运行时,是否有一些特殊的方法可以在 OutOfMemoryError 上从其中获取堆转储?

我尝试过的另一件事是在“启动”和“关闭”选项卡上告诉它使用“Java”选项而不是“jvm”选项。我相信这应该告诉服务管理器尝试使用 Java 可执行命令启动 Tomcat,而不是直接启动 jvm.dll。当我这样做时,服务将无法启动。

肯定有人遇到过类似的问题吗?

【问题讨论】:

我应该提到我已经使用 jconsole 连接到 Tomcat 并观察到堆使用量从未超过 60MB。 【参考方案1】:

在终于把这个放到床上之后,我想为可能有同样问题的其他人回答这个问题。

首先,如果您在 Windows 上安装 Tomcat,请不要使用 .exe 安装程序,即使它是由 Apache 推广的。无论您做什么,它都不会让您以系统帐户以外的任何方式运行 Tomcat。系统帐户似乎没有权限在当前目录中写入.hprof 文件,并且似乎没有任何 Windows 安全调整可以解决此问题。

好的,您已经从.zip 分发版安装了Tomcat。使用service.bat 脚本将其安装为服务。确保将其设置为作为您专门为此目的创建的特定用户运行。还要确保您希望 Tomcat 在发生堆转储时写入的文件夹可由该用户写入。

编辑service.bat 文件,将-XX:+HeapDumpOnOutOfMemoryError-XX:HeapDumpPath=C:\whatever 选项包含在正确的位置(您可以在其中放置JVM 选项)。这应该可以解决问题。

【讨论】:

【参考方案2】:

您是否尝试过 -XX:HeapDumpPath 选项?

http://java.sun.com/javase/technologies/hotspot/vmoptions.jsp

【讨论】:

【参考方案3】:

我找到了以下链接,它描述了如何配置 tomcat 服务(包括设置 java 参数)。不确定它是否适用于您正在运行的版本。

http://tomcat.apache.org/tomcat-5.5-doc/windows-service-howto.html

【讨论】:

谢谢;这确实很有帮助,但我应该提到我正在运行 Tomcat 6。【参考方案4】:

当 java 进程作为窗口服务运行时,您可以使用以下步骤生成 heapdump,

    以管理员身份运行命令控制台 JDK(用于 jmap 命令)和 JRE(Java 应用运行环境)的版本应该相同。 从任务管理器中获取该 java 应用程序正在运行的窗口进程的 PID 号 执行以下命令

jmap -dump:file=d:\heapdump\myHeapDump.hprof -F #PID_No#

如果 JDK/JRE 7 有任何异常,请尝试使用 JDK/JRE 8 实际上,我在使用 JDK 7 的 jmap 中遇到了一些问题,但是当我迁移到 JDK 8 时,我能够使用相同的命令成功生成堆转储

【讨论】:

【参考方案5】:

.hprof 文件转储到当前目录中。任何人都可以猜测这对 Windows 服务意味着什么,假设它意味着什么。

我建议发布一个新问题(在 http://superuser.com 上)询问“当前目录”对于 Windows 服务意味着什么。

【讨论】:

可能是当前目录,但机器上根本没有 .hprof 文件。 所以windows服务可能没有“当前目录”,windows正在将文件转储到void中。我的建议是了解有关 Windows 服务的更多信息。 服务监视器声称当前目录是 C:\Program Files\Apache Tomcat\Tomcat 6.0。我编写了一个 servlet,将文件输出到当前目录,文件显示在该目录中。【参考方案6】:

From 20 Tips for Using Tomcat in Production

将以下内容添加到 catalina.sh(或用于 Windows 的 catalina.bat)中的 JAVA_OPTS:-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/j2ee/heapdumps

【讨论】:

问题当然是服务监视器没有调用任何脚本。【参考方案7】:

如果您使用 .exe 安装了 tomcat,则可以将 tomcat 服务配置为使用本地系统帐户以外的帐户,并且可以在创建转储文件的目录“c:\whatever”上分配该用户权限。这里要记住的一件事是tomcat服务不要使用具有管理权限的帐户运行。所以在windows中创建一个简单的用户(用户组的成员)并将tomcat服务设置为用户这个帐户。并赋予该用户对“c:\whatever”目录的权限。这解决了用户目录权限问题,但您必须为内存转储错误配置 tomcat。

【讨论】:

以上是关于我可以让 Tomcat 作为服务运行以转储堆吗?的主要内容,如果未能解决你的问题,请参考以下文章

tomcat和Java的关系

Tomcat 线程转储

配置 Wildfly 10 以使用 Jackson(作为 JSON 提供程序)

杂集:centos7中利用logrotate工具切割tomcat日志

以编程方式将 Tomcat 的 Java 选项设置为 Windows 服务的方法

Nginx+tomcat集群使用redis共享session