我有一个运行一些应用程序的Tomcat。我无法重启Tomcat,但我想监视类文件的使用情况。
我想记录是否使用了指定的类。这可能吗? 我怎么能完成它?
类用法:如果实例化此类的对象或调用方法等。
澄清:我无法重启应用程序。重新编译正在运行的代码的每个解决方案都是不可接受的。这使问题变得如此困难。
远程调试/ JMX尚未启用。这将类似于重新编译应用程序以激活它。
平台是RHEL,64位。
答案 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启动应用程序以获取有关类加载的信息。