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

时间:2010-01-31 15:32:53

标签: java tomcat hudson heap tomcat6

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

(Tomcat正在运行Hudson,它在我的构建的尾端报告堆空间问题。手动运行构建不会产生这样的错误.Hudson家伙需要堆转储才能开始。)

正如其他地方所述,我告诉Apache Service Monitor通过在JVM选项中添加以下内容来配置运行Tomcat以在遇到OutOfMemoryError时转储堆的JVM: -XX:+ HeapDumpOnOutOfMemoryError 然后我再次运行构建。果然,它报告存在堆错误。我扫描整个磁盘,寻找默认的java_pid123.hprof文件(显然123被JVM的PID取代)。在任何地方都没有.hprof个文件。

我遇到了陷阱22:我需要哈德森人员的堆转储来修复他们的内存泄漏,但如果我在Tomcat下运行Hudson,我就无法获得堆转储。

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

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

当然其他人遇到了类似的问题?

7 个答案:

答案 0 :(得分:6)

最后把这个放到床上之后,我想为那些可能遇到同样问题的人解答这个问题。

首先,如果您在Windows上安装Tomcat,请不要使用.exe安装程序,即使它是由Apache提升的。无论你做什么,它都不会让你将Tomcat作为系统帐户以外的任何东西运行。系统帐户似乎没有在当前目录中写入.hprof文件的权限,并且没有任何Windows安全性调整可能会导致此问题消失。

好的,所以你已经从.zip发行版中安装了Tomcat。使用service.bat脚本将其安装为服务。确保将其设置为以专门为此目的创建的特定用户身份运行。同时确保在堆转储的情况下,Tomcat要写入的文件夹是该用户可写的。

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

答案 1 :(得分:2)

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

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

答案 2 :(得分:1)

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

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

答案 3 :(得分:0)

.hprof文件被转储到当前目录中。对于Windows服务来说,这意味着什么是任何人的猜测,假设它意味着什么。

我建议发布一个新问题(在http://superuser.com上),询问“当前目录”对于Windows服务的含义。

答案 4 :(得分:0)

From 20 Tips for Using Tomcat in Production

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

答案 5 :(得分:0)

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

答案 6 :(得分:0)

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

  1. 以管理员身份运行命令控制台
  2. 版本的JDK(用于jmap命令)和JRE(Java应用程序运行环境)应该是相同的。
  3. 从任务管理器
  4. 获取该Java应用程序的运行窗口进程的PID否
  5. 执行以下命令
  6.   

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

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