简体   繁体   English

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

[英]How to intercept object creation in Java lower than user class level

我正在寻找一些方法,通过使用Java代理或仪器类(最好是比用户类更低级别的东西)拦截JVM中的所有对象创建( new或任何替代方法来创建Object),有一个类似的问题 ,它没有'重点关注Java代理或低于检测用户类的东西

Java Objects can be created in several different ways. 可以通过几种不同的方式创建Java对象。

  1. From Java code , when a Java method, either interpreted or compiled, executes one of the following bytecode instructions: new , newarray , anewarray , multianewarray . 从Java代码中 ,当Java方法(解释或编译)执行以下字节码指令之一时: newnewarrayanewarraymultianewarray
  2. From native code , when native methods, including those in standard class library, call one of JNI functions: NewObject , NewObjectArray , NewStringUTF , NewDirectByteBuffer , etc. 从本机代码开始 ,当本机方法(包括标准类库中的方法)调用JNI函数之一时: NewObjectNewObjectArrayNewStringUTFNewDirectByteBuffer等。
  3. Directly from VM runtime , when a new object is created internally by JVM, for example, in response to Object.clone() , Throwable.getStackTrace() , Class.getInterfaces() , etc. 直接来自VM运行时 ,当JVM在内部创建新对象 ,例如,响应Object.clone()Throwable.getStackTrace()Class.getInterfaces()等。

Unfortunately, there is no single point where you can collect objects from all these sources. 不幸的是,没有一点可以从所有这些来源收集对象。 However, there are means for intercepting all of them. 但是,有办法拦截所有这些。

  1. Objects instantiated from Java can be caught by an Instrumentation agent. 从Java实例化的对象可以由Instrumentation代理捕获。 The agent needs to define a ClassFileTransformer that will scan the bytecode of all loaded classes for object-creating instructions and modify it. 代理需要定义一个ClassFileTransformer ,它将扫描所有已加载类的字节码以获取对象创建指令并对其进行修改。

    Note: there is no need to intercept all new instructions, you can instrument Object() constructor instead. 注意:没有必要拦截所有new指令,可以改为使用Object()构造函数。 But you still need to intercept array allocation instructions. 但是你仍然需要拦截数组分配指令。

  2. JNI functions can be intercepted by JVMTI agent. JVMI代理可以拦截JNI函数。 You need to define your own native hooks for NewObjectArray , NewStringUTF etc. and then replace JNI function table. 您需要为NewObjectArrayNewStringUTF等定义自己的本机挂钩,然后替换JNI函数表。 See JVMTI Reference for the details. 有关详细信息,请参阅JVMTI参考

  3. Objects created by the VM can be caught by JVMTI Event Callback mechanism . 由VM创建的对象可以由JVMTI事件回调机制捕获。 The desired event is VMObjectAlloc . 所需的事件是VMObjectAlloc

    Note: JVM will not post VMObjectAlloc event for objects allocated from Java or by JNI functions. 注意:JVM不会为从Java或JNI函数分配的对象发布VMObjectAlloc事件。

All other ways of object instantiation (cloning, reflection, deserialization) fall into one of the above categories. 对象实例化(克隆,反射,反序列化)的所有其他方式都属于上述类别之一。


Get JDK 8 Demos and Samples from Oracle Java SE Downloads website. 从Oracle Java SE下载网站获取JDK 8演示和示例。
There is a sample JVMTI agent for exactly this question. 对于这个问题,有一个示例JVMTI代理。

Look under 看下

  • jvmti/heapTracker
  • jvmti/hprof

You can take a look at this opensource java agent created by devexperts team https://github.com/Devexperts/aprof It provides nice reports to detect where memory is allocated. 您可以查看由devexperts团队创建的这个opensource java代理https://github.com/Devexperts/aprof它提供了很好的报告来检测内存的分配位置。 But, as i know, it doesn't intercept new objects created via JNI or sun.misc.Unsafe.allocateInstance in current version 但是,据我所知,它不拦截通过JNI或sun.misc.Unsafe.allocateInstance在当前版本中创建的新对象

It is pure java agent which manipulates bytecode with ASM. 它是纯java代理,它使用ASM操作字节码。 Before each object allocation aprof inserts method call which traks allocation size and location stack (where this allocation occurs) 在每个对象分配之前,aprof会插入方法调用,该方法调用会分配大小和位置堆栈(发生此分配的位置)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM