是否可以记录是否使用了JVM中的类?

时间:2010-02-11 09:00:29

标签: java jvm

我有一个运行一些应用程序的Tomcat。我无法重启Tomcat,但我想监视类文件的使用情况。

我想记录是否使用了指定的类。这可能吗? 我怎么能完成它?

类用法:如果实例化此类的对象或调用方法等。

澄清:我无法重启应用程序。重新编译正在运行的代码的每个解决方案都是不可接受的。这使问题变得如此困难。

远程调试/ JMX尚未启用。这将类似于重新编译应用程序以激活它。

平台是RHEL,64位。

7 个答案:

答案 0 :(得分:1)

我认为你需要对其进行分析。 Profiler将允许您查看使用的类。 或者程序员喜欢 - System.out.println:)

答案 1 :(得分:1)

  

我想记录是否使用了指定的类;即,如果实例化此类的对象或调用方法等。

内存探查器会告诉您在运行探查器的瞬间是否存在可访问的类实例。执行分析器可以告诉您在某个时间间隔内调用方法或构造函数...虽然它可能也会错过调用,因为分析器的工作方式。

webapp的类加载器理论上可以告诉你是否已经加载了一个类,但我怀疑是否有办法调用不涉及重启的类加载器方法。此外,除了向类添加监视挂钩之外,无法知道方法是否已调用EVER或是否已创建实例。并添加这些钩子将需要重新启动。

当然还有其他方法可以“使用”类,而不需要构造实例或调用其方法。

因此,根据您的想法,您可能会失去运气。

答案 2 :(得分:0)

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

如果对象实例化不是“类文件的用法”的意思,那么也许你的意思是你想知道JVM何时加载一个类?如果是这样,static initialization blocks可能会有所帮助;你可以把日志语句放在那里。

答案 3 :(得分:0)

如果你想以编程方式知道它,那么我认为这不是一件容易的事。

但是你可以通过调用这种方法来做一些反思来了解。

ClassLoader#findLoadedClass()

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

答案 4 :(得分:0)

如果您使用的是Solaris或OS X,则可以选择DTrace探测。

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

答案 5 :(得分:-1)

您可以在类

中定义静态块
class X {
 static {
  System.out.println("class X has been loaded");
 }
 ...
}

在加载类对象时将被调用一次。

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

jmap -histo <pid>

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

使用jps你可以找到pid

答案 6 :(得分:-1)

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