在JVM中,是否有可能记录一个类是否被使用?

5
我有一个Tomcat和一些应用正在运行。我无法重新启动Tomcat,但我想要监控类文件的使用情况。
我想记录特定类是否被使用。这可行吗?如何实现?
类的使用:如果实例化该类的对象或调用方法等。
澄清:我不能重新启动应用程序。任何需要重新编译正在运行代码的解决方案都是不可接受的。这使问题变得非常困难。
远程调试/JMX尚未启用。这将是一个类似于重新编译应用程序以激活它的工作量。
平台为RHEL,64位。

3
请说明您所说的类是否被“使用”的含义。 - Nate W.
你能确认一下平台吗? - Tom Duckering
1
远程调试、JMX或其他任何东西是否已经在Tomcat实例上设置好了?如果没有,你可能就没什么办法了... - Nate
7个回答

1

我认为你需要进行性能分析。 性能分析器将允许您查看使用了哪些类。 或者程序员最喜欢的 - System.out.println :)


1
我认为性能分析需要在JVM上进行设置,这些设置需要重新启动才能生效。 - Tom Duckering

1
我想记录指定类是否被使用;即,是否实例化了此类的对象或调用了方法等。
内存分析器将告诉您在运行分析器的瞬间是否存在可达类的实例。执行分析器可以告诉您在某个时间间隔内调用了某个方法或构造函数...尽管它也可能会错过调用,这是由分析器的工作方式决定的。
Web应用程序的类加载器理论上可以告诉您是否已加载了类,但我怀疑没有一种不涉及重新启动的调用类加载器方法的方法。此外,除了向类添加监视挂钩之外,没有办法知道是否曾经调用过方法或创建过实例。而添加这些挂钩将需要重新启动。
当然,还有其他一些类可能被“使用”的方式,并不涉及构建实例或调用其方法。
因此,取决于您真正想弄清楚的内容,您可能会很倒霉。

0

如果你想以编程的方式了解它,我认为这并不是一件容易的事情。

但是你可以通过调用这个方法来进行一些反射操作来了解它。

ClassLoader#findLoadedClass()

如果方法返回 null,则表示该类未加载,因此未被使用。 当然问题在于该方法是受保护的,因此您需要使用反射。

0

如果您可以访问源文件,您可以在类的构造函数中放置一些日志语句(假设实例化意味着类使用)。

如果对象实例化不是您所说的“类文件的使用”,那么也许您想知道何时JVM加载类? 如果是这样,静态初始化块可能能够帮助您; 您可以在那里放置日志语句。


1
如果他无法重新启动Tomcat,那么他可能也无法更新应用程序代码。 - Thilo
你似乎不太确定。我记得曾经将.jar文件放到你的Tomcat目录中进行动态部署。 - Nate W.
我听起来不确定,因为OP在他的需求上并不清楚。如果重启Tomcat是不允许的,热部署可能也被禁止了(也许首先更新源代码也是如此)。 - Thilo
热部署也不起作用。感谢Thilo的澄清。将.jar文件放入Tomcat中会重新启动应用程序。 - guerda

0

如果你使用的是Solaris或OS X操作系统,那么DTrace探针可能是一个选项。

除此之外,如果你无法将调试器、分析器或其他监控工具附加到已经运行的JVM上(这取决于你在启动时需要指定的选项),那么你就没有办法了。


Solaris也有pfilestruss - Tom Duckering

-1
你可以在类中定义一个静态块
class X {
 static {
  System.out.println("class X has been loaded");
 }
 ...
}

当类对象被加载时,该函数将被调用一次。

如果您无法编辑代码,并且您有JRE 6,则可以尝试jmap工具。

jmap -histo <pid>

它将打印出堆的直方图,包括所有已加载的类。

使用 jps 命令可以找到进程 ID。


好的想法。对于我的问题,它行不通,因为我无法重新编译应用程序。 - guerda

-1

使用JRockit JVM,您可以通过-Xverbose:class=info启动应用程序以获取有关类加载的信息。


Sun的JVM也支持该标志。 - Thilo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接