java - 获取 String.equals 调用跟踪

标签 java profiling stack-trace backtrace

我看到我可以像这样打印当前堆栈跟踪: 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/

相关文章:

java - 将 Websockets 实现到我的 Tomcat Servlet 中?

java - 如何检测未引用或双引号的空格

java - Clojure 中的 "long... numbers"参数相当于什么?

windows-8.1 - 仅为提供程序中的某些特定 ETW 任务激活堆栈?

java - brew cask install java8 安装失败

java - 如何从 JVisualVM 获取峰值内存使用情况快照?

visual-studio - Visual Studio 2005 中的代码分析

oracle - 从哪里获得 Oracle TKPROF.exe 实用程序?

bug-tracking - 自动将意外错误/堆栈跟踪记录到错误跟踪器的建议

c++ - VC++ 堆栈跟踪不解析生产中的函数名称