日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

jvmti_拥有您的堆:使用JVMTI迭代类实例

發布時間:2023/12/3 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 jvmti_拥有您的堆:使用JVMTI迭代类实例 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

jvmti

今天,我想談一談我們大多數人每天都不會看到和使用的另一種Java,更確切地說,是有關較低級別的綁定,一些本機代碼以及如何執行一些小的魔術。 盡管我們不會在JVM上找到真正的魔力源,但是在單個帖子的范圍內可以實現一些小奇跡。

我花了很多時間在ZeroTurnaround的RebelLabs團隊中進行研究,編寫和編碼,該公司為Java開發人員創建工具,這些工具主要以javaagents的身份運行。 通常情況下,如果您想在不重寫JVM的情況下增強JVM或在JVM上獲得任何強大的功能,則必須深入研究Java代理的美麗世界。 它們有兩種形式:Java javaagents和本機Javaagents。 在這篇文章中,我們將集中討論后者。


注意, XRebel產品負責人Anton Arhipov的這個GeeCON Prague演示文稿是學習完全用Java編寫的Javaagents的一個很好的起點: 與Javassist一起玩 。

在本文中,我們將創建一個小型的本機JVM代理,探討將本機方法公開到Java應用程序中的可能性,并了解如何利用Java虛擬機工具接口 。

如果您正在尋找帖子的實用內容,我們將能夠在擾亂警報的情況下計算堆中存在給定類的實例數量。

想象一下,您是圣誕老人值得信賴的黑客精靈,而這位大人物對您來說面臨以下挑戰:

圣誕老人: 我親愛的Hacker Elf,您能否編寫一個程序來指出JVM堆中當前隱藏了多少個Thread對象?

另一個不愿意挑戰自己的小精靈會回答: 這很容易直接,對嗎?

return Thread.getAllStackTraces().size();

但是,如果我們想對我們的解決方案進行過度設計以能夠回答有關任何給定類的問題,該怎么辦? 說我們要實現以下接口?

public interface HeapInsight {int countInstances(Class klass); }

是的,那是不可能的,對吧? 如果您收到String.class作為參數怎么辦? 不用擔心,我們只需要更深入地研究JVM的內部結構。 JVMTI作者可以使用的一件事是JVMTI (Java虛擬機工具接口)。 它是很久以前添加的,許多看似神奇的工具都在使用它。 JVMTI提供了兩件事:

  • 本機API
  • 一種工具API,用于監視和轉換裝入JVM的類的字節碼。

就我們的示例而言,我們需要訪問本機API。 我們要使用的是IterateThroughHeap函數,該函數使我們可以提供一個自定義回調,以對給定類的每個對象執行該回調。

首先,讓我們創建一個本地代理,該代理將加載和回顯某些內容,以確保我們的基礎架構能夠正常工作。

本機代理程序是用C / C ++編寫的,并被編譯成動態庫,以便在我們甚至開始考慮Java之前就進行加載。 如果您不精通C ++,請不要擔心,沒有很多精靈,也不會很難。 我的C ++方法包括2種主要策略:巧合編程和避免段錯誤。 因此,由于我設法編寫了這篇文章的示例代碼并對其進行了注釋,因此我們可以一起研究一下。 注意:以上段落應作為免責聲明,請勿將此代碼置于任何對您有價值的環境中。

這是創建第一個本機代理的方法:

#include #include using namespace std;JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) {cout << "A message from my SuperAgent!" << endl;return JNI_OK; }

該聲明的重要部分是聲明一個名為Agent_OnLoad的函數,該函數遵循動態鏈接的代理的文檔 。

將文件另存為例如native-agent.cpp ,讓我們看看我們可以做些什么來變成一個庫。

我在OSX上,因此我使用clang對其進行編譯,以節省一些時間,下面是完整的命令:

clang -shared -undefined dynamic_lookup -o agent.so -I /Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/include/ -I /Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/include/darwin native-agent.cpp

這將創建一個agent.so文件,該文件是可以為我們服務的庫。 為了測試它,讓我們創建一個虛擬的hello world Java類。

package org.shelajev; public class Main {public static void main(String[] args) {System.out.println("Hello World!");} }

當你用正確的-agentpath選項指向agent.so運行它,你應該看到下面的輸出:

java -agentpath:agent.so org.shelajev.Main A message from my SuperAgent! Hello World!

很好! 現在,我們擁有一切使之真正有用的地方。 首先,我們需要一個jvmtiEnv實例,當我們位于Agent_OnLoad中時 ,可以通過JavaVM * jvm獲得該實例 ,但以后將不可用。 因此,我們必須將其存儲在全球可訪問的位置。 我們通過聲明一個全局結構來存儲它。

#include #include using namespace std;typedef struct {jvmtiEnv *jvmti; } GlobalAgentData;static GlobalAgentData *gdata;JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) {jvmtiEnv *jvmti = NULL;jvmtiCapabilities capa;jvmtiError error;// put a jvmtiEnv instance at jvmti.jint result = jvm->GetEnv((void **) &jvmti, JVMTI_VERSION_1_1);if (result != JNI_OK) {printf("ERROR: Unable to access JVMTI!\n");}// add a capability to tag objects(void)memset(∩a, 0, sizeof(jvmtiCapabilities));capa.can_tag_objects = 1;error = (jvmti)->AddCapabilities(∩a);// store jvmti in a global datagdata = (GlobalAgentData*) malloc(sizeof(GlobalAgentData));gdata->jvmti = jvmti;return JNI_OK; }

我們還更新了代碼,以添加標記對象的功能,這是我們遍歷堆所需的。 現在準備工作已經完成,我們已經初始化了JVMTI實例并且可供我們使用。 讓我們通過JNI將其提供給我們的Java代碼。

JNI代表Java本機接口 ,這是將本機代碼調用包含到Java應用程序中的一種標準方式。 Java部分將非常簡單明了,將以下countInstances方法定義添加到Main類:

package org.shelajev;public class Main {public static void main(String[] args) {System.out.println("Hello World!");int a = countInstances(Thread.class);System.out.println("There are " + a + " instances of " + Thread.class);}private static native int countInstances(Class klass); }

為了適應本機方法,我們必須更改本機代理代碼。 我將在稍后解釋,但現在在其中添加以下函數定義:

extern "C" JNICALL jint objectCountingCallback(jlong class_tag, jlong size, jlong* tag_ptr, jint length, void* user_data) {int* count = (int*) user_data;*count += 1; return JVMTI_VISIT_OBJECTS; }extern "C" JNIEXPORT jint JNICALL Java_org_shelajev_Main_countInstances(JNIEnv *env, jclass thisClass, jclass klass) {int count = 0;jvmtiHeapCallbacks callbacks; (void)memset(&callbacks, 0, sizeof(callbacks)); callbacks.heap_iteration_callback = &objectCountingCallback;jvmtiError error = gdata->jvmti->IterateThroughHeap(0, klass, &callbacks, &count);return count; }

Java_org_shelajev_Main_countInstances在這里更有趣,它的名稱遵循約定,以Java_開頭,然后是_分隔的完全限定的類名,然后是Java代碼中的方法名。 另外,請不要忘記JNIEXPORT聲明,該聲明指出該函數已導出到Java世界中。

在Java_org_shelajev_Main_countInstances內部,我們將objectCountingCallback函數指定為回調,并使用Java應用程序中的參數調用IterateThroughHeap 。

請注意,我們的本機方法是靜態的,因此C對應項中的參數為:

JNIEnv *env, jclass thisClass, jclass klass

對于實例方法,它們將有所不同:

JNIEnv *env, jobj thisInstance, jclass klass

這里的thisInstance指向Java方法調用的this對象。

現在, objectCountingCallback的定義直接來自文檔 。 身體無非就是增加一個int。

繁榮! 全做完了! 感謝您的耐心等待。 如果您仍在閱讀本文,則可以測試上面的所有代碼。

再次編譯本機代理并運行Main類。 這是我看到的:

java -agentpath:agent.so org.shelajev.Main Hello World! There are 7 instances of class java.lang.Thread

如果我添加一個線程t = new Thread(); 行到main方法,我在堆上看到8個實例。 聽起來好像真的可行。 您的線程數幾乎肯定會有所不同,不用擔心,這是正常現象,因為它確實計入了JVM簿記線程,進行編譯,GC等操作。

現在,如果我要計算堆上String實例的數量,只需更改參數類即可。 我希望圣誕老人是一個真正通用的解決方案。

哦,如果您有興趣,它會為我找到2423個String實例。 對于小型應用程序來說,這個數字相當高。 也,

return Thread.getAllStackTraces().size();

給我5個而不是8個,因為它不包括簿記線程! 談論瑣碎的解決方案,是嗎?

現在,您已經掌握了這些知識,并且知道了本教程,并不是說您已經準備好編寫自己的JVM監視或增強工具,但這絕對是一個開始。

在本文中,我們從零開始編寫了本機Java代理,該代理成功編譯,加載和運行。 它使用JVMTI來獲取無法通過其他方式訪問的JVM的見解。 相應的Java代碼調用本機庫并解釋結果。

這通常是最神奇的JVM工具所采用的方法,我希望其中的一些魔術已為您揭開神秘面紗。

翻譯自: https://www.javacodegeeks.com/2014/12/own-your-heap-iterate-class-instances-with-jvmti.html

jvmti

總結

以上是生活随笔為你收集整理的jvmti_拥有您的堆:使用JVMTI迭代类实例的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: av在线播放中文字幕 | 理论片第一页 | 欧美激情一区二区三级高清视频 | 短视频在线观看 | 91视频高清 | 国产精品刘玥久久一区 | 88av网站 | 久久久精品视频网站 | 一节黄色片| 国产美女精品人人做人人爽 | 国产人妻黑人一区二区三区 | 可以免费看的av网站 | 在线欧美a | 伊人久久国产精品 | 欧美成人aaaaⅴ片在线看 | 亚洲国产美女视频 | 精品国产欧美一区二区三区成人 | 久久精品a亚洲国产v高清不卡 | 97超视频在线观看 | 亚洲色图另类图片 | 久久精品视频一区 | 免费成人av片 | 天天爱天天舔 | 国产tv在线观看 | 在线视频第一页 | 91成人天堂久久成人 | 狠狠干超碰 | 久久久久久久久久久久久久久久久久久 | 午夜精品久久久久久久99热黄桃 | 亚洲成年人影院 | 亚洲天堂精品一区 | 欧美成人做爰大片免费看黄石 | 黄色骚视频| 欧美日韩成人在线视频 | 一卡二卡三卡 | 激情文学8888 | 日本69少妇 | 久久久96人妻无码精品 | 色综合网站 | 国产精品啪 | 中文字幕校园春色 | 久久最新免费视频 | 色噜噜狠狠一区二区三区牛牛影视 | 99热官网| 香蕉视频网站在线观看 | 91在线免费网站 | 四虎5151久久欧美毛片 | 尤物视频一区 | 视频二区| 中文字幕第一页久久 | 噜噜噜色 | 美女毛片网站 | www.欧美在线 | 国产精品久久国产精麻豆96堂 | 一级黄色伦理片 | 自慰无码一区二区三区 | 高清日韩一区二区 | 天堂av亚洲av国产av电影 | 97干在线| 大尺度做爰呻吟舌吻网站 | 久久中文字幕一区二区 | 国产真人无遮挡作爱免费视频 | 浮力影院国产第一页 | 日韩欧美一区二区免费 | 亚洲AV不卡无码一区二区三区 | 欧美亚洲综合在线 | 波多野吉衣一二三区乱码 | 影音先锋毛片 | 亚洲一区二区三 | 久久久久久久一区二区 | 蜜桃视频一区二区三区在线观看 | 精品xxxxx| 中文在线а√天堂 | 在线欧美亚洲 | 国产综合网站 | 奶水喷溅虐奶乳奴h文 | 亚洲一区二区91 | 国产精品国产三级国产专区51 | www.精品 | 久久成人在线视频 | 日本嫩草影院 | 久久久久黄色 | 日韩av成人在线观看 | 亚洲 欧美 自拍偷拍 | 污视频91| 波多野结衣之潜藏淫欲 | 无码人妻一区二区三区在线 | 美女乱淫 | 欧美浪妇xxxx高跟鞋交 | 免费污视频 | 狠狠干天天干 | 日本亚洲欧美在线 | 99精品无码一区二区 | 中文字幕第23页 | 欧美成人片在线观看 | 欧美另类精品xxxx孕妇 | 成年人网站免费 | 亚洲国产成人精品久久久 | 久久久久无码国产精品一区 |