我看到我可以像这样打印当前堆栈跟踪: Get current stack trace in Java .
但我想跟踪每个 String.equals
调用,但我不知道该怎么做(我不知道这些调用是在哪里进行的,因为我使用的是库)。
我想知道何时进行这些调用以提高我的代码的性能。
编辑:根据回答的数量,可能我的问题不清楚:
我想跟踪我的 Java 程序中 String.equals()
的每次调用,我不关心方法。 ;)
最佳答案
我非常怀疑许多 JVM 都支持这一点。拦截每个方法调用的一种可能方法是使用 Java Instrumentation API 检测字节码。 .
问题是类主要可以在加载类时进行检测。因此,虽然我建议的方法适用于您的应用程序类,但 JVM 已经预加载了 String
类。要修改加载的类,JVM 应该支持类 retransform
或类 redefine
。您可以使用下一个简单的 Maven 项目来检查这一点:
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.stackoverflow.questions</groupId>
<artifactId>stringequalscall</artifactId>
<version>0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<archive>
<manifestEntries>
<PreMain-Class>com.stackoverflow.questions.stringequalscall.Agent</PreMain-Class>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>
src/main/java/com/stackoverflow/questions/stringequalscall/Agent.java:
package com.stackoverflow.questions.stringequalscall;
import java.lang.instrument.Instrumentation;
public class Agent {
public static void premain(String args, Instrumentation instrumentation) {
System.out.println("Can redefine classes: " + instrumentation.isRedefineClassesSupported());
System.out.println("Can retransform classes: " + instrumentation.isRetransformClassesSupported());
System.out.println("String modifiable: " + instrumentation.isModifiableClass(String.class));
}
}
src/main/java/com/stackoverflow/questions/stringequalscall/AgentTest.java:
package com.stackoverflow.questions.stringequalscall;
public class AgentTest {
public static void main(String[] args) {
System.out.println("Executing Agent test");
}
}
构建 JAR:
mvn clean install
然后从您的 target
文件夹运行
java -javaagent:stringequalscall-0.1-SNAPSHOT.jar com.stackoverflow.questions.stringequalscall.AgentTest
如果您的 JVM 支持上述加载类操作方法之一,那么您可以尝试编写自己的 Java 代理,将执行跟踪添加到 String#equals(String)
。
对于我在 Oracle Java 9 上的输出是:
Can redefine classes: false
Can retransform classes: false
String modifiable: true
Executing Agent test
顺便说一句,您为什么认为 String#equals(String)
可能是性能问题的根源?
附言至少编写简单的 Java 代理很有趣。
关于java - 获取 String.equals 调用跟踪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46916295/