[英]How to intercept object creation in Java lower than user class level
我正在尋找一些方法,通過使用Java代理或儀器類(最好是比用戶類更低級別的東西)攔截JVM中的所有對象創建( new
或任何替代方法來創建Object),有一個類似的問題 ,它沒有'重點關注Java代理或低於檢測用戶類的東西
可以通過幾種不同的方式創建Java對象。
new
, newarray
, anewarray
, multianewarray
。 NewObject
, NewObjectArray
, NewStringUTF
, NewDirectByteBuffer
等。 Object.clone()
, Throwable.getStackTrace()
, Class.getInterfaces()
等。 不幸的是,沒有一點可以從所有這些來源收集對象。 但是,有辦法攔截所有這些。
從Java實例化的對象可以由Instrumentation代理捕獲。 代理需要定義一個ClassFileTransformer ,它將掃描所有已加載類的字節碼以獲取對象創建指令並對其進行修改。
注意:沒有必要攔截所有new
指令,可以改為使用Object()
構造函數。 但是你仍然需要攔截數組分配指令。
JVMI代理可以攔截JNI函數。 您需要為NewObjectArray
, NewStringUTF
等定義自己的本機掛鈎,然后替換JNI函數表。 有關詳細信息,請參閱JVMTI參考 。
由VM創建的對象可以由JVMTI事件回調機制捕獲。 所需的事件是VMObjectAlloc 。
注意:JVM不會為從Java或JNI函數分配的對象發布VMObjectAlloc
事件。
對象實例化(克隆,反射,反序列化)的所有其他方式都屬於上述類別之一。
從Oracle Java SE下載網站獲取JDK 8演示和示例。
對於這個問題,有一個示例JVMTI代理。
看下
jvmti/heapTracker
jvmti/hprof
您可以查看由devexperts團隊創建的這個opensource java代理https://github.com/Devexperts/aprof它提供了很好的報告來檢測內存的分配位置。 但是,據我所知,它不攔截通過JNI或sun.misc.Unsafe.allocateInstance在當前版本中創建的新對象
它是純java代理,它使用ASM操作字節碼。 在每個對象分配之前,aprof會插入方法調用,該方法調用會分配大小和位置堆棧(發生此分配的位置)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.