java - 如何在低于用户类级别的Java中拦截对象创建

标签 java jvm

我正在寻找一些方法,通过使用 Java 代理或检测类(最好是比用户类更低级别的东西)来拦截 JVM 中的所有对象创建(new 或任何其他创建对象的方法), 有一个 similar question它不关注 Java 代理或低于检测用户类的东西

最佳答案

Java 对象可以用几种不同的方式创建。

  1. 从 Java 代码,当解释或编译的 Java 方法执行以下字节码指令之一时:new , newarray , anewarray , multianewarray .
  2. 从 native 代码,当 native 方法(包括标准类库中的方法)调用 JNI 函数之一时:NewObject , NewObjectArray , NewStringUTF , NewDirectByteBuffer
  3. 直接从 VM 运行时,当 JVM 在内部创建新对象时,例如,响应 Object.clone()Throwable.getStackTrace (), Class.getInterfaces()

不幸的是,没有一个单一的点可以让您从所有这些来源收集对象。但是,有办法拦截所有这些。

  1. 从 Java 实例化的对象可以被 Instrumentation 捕获代理人。代理需要定义一个 ClassFileTransformer它将扫描所有已加载类的字节码以查找对象创建指令并对其进行修改。

    注意:不需要拦截所有的 new 指令,您可以检测 Object() 构造函数。但是你仍然需要拦截数组分配指令。

  2. JNI 函数可以被 JVMTI 代理拦截。您需要为NewObjectArrayNewStringUTF 等定义自己的原生钩子(Hook),然后替换JNI 函数表。参见 JVMTI Reference了解详情。

  3. VM 创建的对象可以被 JVMTI Event Callback mechanism 捕获.所需的事件是 VMObjectAlloc .

    注意:JVM 不会为从 Java 或 JNI 函数分配的对象发布 VMObjectAlloc 事件。

对象实例化的所有其他方式(克隆、反射、反序列化)都属于上述类别之一。


从 Oracle 获取 JDK 8 演示和样本 Java SE Downloads网站。
有一个示例 JVMTI 代理正是针对这个问题。

往下看

  • jvmti/heapTracker
  • jvmti/hprof

关于java - 如何在低于用户类级别的Java中拦截对象创建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35924300/

相关文章:

jvm - 开源、多 JVM 监视器 Web 应用程序选项?

java - Apache Commons 压缩无法在 tar 中添加硬链接(hard link)

java - 最好使用的 keystore 是什么?

java - 将 string[] 转换为逗号分隔的字符串。

java - native 方法和平台独立性

java - 避免 jvm 崩溃日志

java - 在 32 位平台上使用 Java DJNativeSwing 库时出现问题

java - 所有鼠标事件监听器执行完毕后调用一段代码

jvm - Gradle 应用程序插件 : How can I run jvm application with -javaagent options?

java - 线程结束工作后,JVM不会释放字节数组的内存