我有一台 Windows 服务器,上面有一个第三方应用程序,它作为 Windows 服务运行。该服务/应用程序实际上是一个 Java 虚拟机,但它在任务管理器中显示为 exe(我们称之为foo.exe
)。
我知道该程序旨在从注册表中获取 JVM 堆大小分配首选项,并且我知道它在注册表中的哪个位置查找该信息。话虽如此,我不确定管理员是否在启动服务之前(或之后)编辑了注册表。
由于这是一个生产系统,我不愿意重新启动服务(特别是如果它已经在使用我现在在注册表中看到的堆分配值)。有没有其他方法可以在不重新启动服务的情况下告诉我?我想我可以在任务管理器中查看当前使用的内存,但这样无法提供准确的值。
答案1
在任务管理器中显示命令行列,该列应该具有假设在命令行上传递的设置:
答案2
请注意以下答案可能需要启用 JMX - 我相信它在公共 JRE 中默认被禁用,并且需要重新启动 JVM 才能更改它,这对你的情况来说毫无用处。不过,值得一试吗?
它们是否有效还取决于该应用程序所使用的特定本机包装方法。
您应该能够将这些工具连同与jli.dll
次要版本和体系结构相匹配的 JDK 一起复制到您正在运行的 JRE。您也可以远程运行这些工具,但由于远程连接的安全要求,如果不进行一些初始设置,这种方法不太可能奏效。
这jps
JDK 中的工具应该能够使用命令提供此信息jps -v
。如果您有多个 Java 进程正在运行,则可以通过第一列中的 PID 来识别它们。
Netbeans (PID 9056) 上的示例输出(使用与您的应用程序类似的本机包装器):
9056 -Dnetbeans.importclass=org.netbeans.upgrade.AutoUpgrade -Dnetbeans.accept_
license_class=org.netbeans.license.AcceptLicense -client -Xss2m -Xms32m -XX:Perm
Size=32m -Dapple.laf.useScreenMenuBar=true -Dapple.awt.graphics.UseQuartz=true -
Dsun.java2d.noddraw=true -Dsun.java2d.dpiaware=true -Dsun.zip.disableMemoryMappi
ng=true -Xmx1024m <snip>
注意-Xss
,-Xms
和-Xmx
参数。
您可以尝试的另一件事是jinfo
,它允许您定位特定的 PID,例如jinfo 9056
。
注意 - 此实用程序不受支持,并且在 JDK 的未来版本中可能会或可能不会提供。
您也可以尝试jconsole
,jvisualvm
但从我的测试来看,它们似乎无法附加到包装的 JVM 并列出 VM 参数。
答案3
在“C:\Program Files (x86)\Foo Vender”下查找任何包含字符串的文本文件-Xms
--Xmx
它可能正在从文件中提取值INI
。如果没有,它可能正在从注册表的某个地方获取它们,正如您所猜测的那样。我的一个客户使用作为 Windows 服务运行的 Web 代理,并从其安装的注册表项中获取启动参数。
如果您想确认在 EXE 启动期间读取了哪些文件或注册表项,请在启动服务时使用 Sysinternals 的 ProcMon。