簡體   English   中英

如何攔截Java中的對象創建低於用戶類級別

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

我正在尋找一些方法,通過使用Java代理或儀器類(最好是比用戶類更低級別的東西)攔截JVM中的所有對象創建( new或任何替代方法來創建Object),有一個類似的問題 ,它沒有'重點關注Java代理或低於檢測用戶類的東西

可以通過幾種不同的方式創建Java對象。

  1. 從Java代碼中 ,當Java方法(解釋或編譯)執行以下字節碼指令之一時: newnewarrayanewarraymultianewarray
  2. 從本機代碼開始 ,當本機方法(包括標准類庫中的方法)調用JNI函數之一時: NewObjectNewObjectArrayNewStringUTFNewDirectByteBuffer等。
  3. 直接來自VM運行時 ,當JVM在內部創建新對象 ,例如,響應Object.clone()Throwable.getStackTrace()Class.getInterfaces()等。

不幸的是,沒有一點可以從所有這些來源收集對象。 但是,有辦法攔截所有這些。

  1. 從Java實例化的對象可以由Instrumentation代理捕獲。 代理需要定義一個ClassFileTransformer ,它將掃描所有已加載類的字節碼以獲取對象創建指令並對其進行修改。

    注意:沒有必要攔截所有new指令,可以改為使用Object()構造函數。 但是你仍然需要攔截數組分配指令。

  2. JVMI代理可以攔截JNI函數。 您需要為NewObjectArrayNewStringUTF等定義自己的本機掛鈎,然后替換JNI函數表。 有關詳細信息,請參閱JVMTI參考

  3. 由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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM