I very much doubt that this is supported by many JVMs. One of the possible ways to intercept each method call is to instrument bytecode with Java Instrumentation API.
The issue is that classes mainly can be instrumented at the moment of class being loaded. So while the approach I suggest works well for you application classes, String
class will be already preloaded by JVM. To modify loaded classes JVM should support either class retransform
or class redefine
. You can check this with next simple Maven project:
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");
}
}
build JAR:
mvn clean install
And from your target
folder run
java -javaagent:stringequalscall-0.1-SNAPSHOT.jar com.stackoverflow.questions.stringequalscall.AgentTest
If you JVM supports one of the mentioned loaded class manipulation methods then you can try to write your own Java agent that can add execution tracking to String#equals(String)
.
For me on Oracle Java 9 the output is:
Can redefine classes: false
Can retransform classes: false
String modifiable: true
Executing Agent test
BTW why do you believe that String#equals(String)
may be the source of your performance problems?
P.S. At least it was fun writing simple Java agent.