簡體   English   中英

如何獲取Java堆的內存地址?

[英]How to get the memory address of the Java heap?

如何確定當前進程中運行的JVM的Java堆內存地址? 也就是說,使用Java,C或其他調用獲取一個void *指針或等效於JVM為堆分配的內存的連續區域?

Matlab在其進程中嵌入了JVM。 JVM分配的內存對於Matlab數組是不可用的,而且這一點很重要,因為它占用了大量連續的內存並且從不收縮,而Matlab也需要連續的內存用於其數組。 如果在擴展期間重新分配堆,則可能導致碎片。

我想檢查我的進程來檢查Java堆和Matlab的內存視圖之間的交互,並找出它由於調整大小而移動的時間,最好是在進程內。 這需要堆的地址。 從java.lang.Runtime很容易找到堆大小,但在內存中找不到它的地址。 如何才能做到這一點?

我在Windows XP和Server 2003上的Matlab R2008b進程中運行Sun的JRE 1.6.0_04。我意識到這可能需要特定於供應商的技術。 該過程運行我們編寫的代碼,因此我們可以使用自定義Java,Matlab,JNI和C / C ++代碼。 JVM中的Java方法調用或支持的鈎子優先於低級別的hackery。

編輯:這個目的是檢查JVM的GC和Matlab的GC之間的相互作用。 我沒有必要查看Java堆,也不會從該內存中讀取任何內容; 我只想看看它在整個虛擬內存空間的上下文中,Matlab的GC也試圖將數據放入其中。

獲取JVM的實際堆地址的快速方法是跳轉到WinDbg,附加到JVM並發出單個!地址命令。 大概在0x2左右??????? (它在jvm版本之間存在差異,但對於該版本保持靜態)將是一個標記為PAGE_EXECUTE_READWRITE的大型VAD,這是您進程內存中的JVM堆。

要確認,您可以在kernel32!VirtualAlloc上設置斷點,並在模塊JVM.DLL中啟動JVM時,您將點擊對VirtualAlloc的調用,向您顯示其堆的jvm分配。 如果您查看此調用的代碼,您可以看到地址的計算方式。

退一步......你能用固定大小的Java堆嗎? 那時對重新分配和分裂的擔憂消失了。

在獨立的Java調用中,涉及為500Mb堆指定-Xmx500m和-Xms500m之類的東西。 你必須把它翻譯成matlab想要的東西。

如果您只想讓JVM堆縮小,可以嘗試使用gc參數,例如-XX:MaxHeapFreeRatio(請參閱http://java.sun.com/javase/technologies/hotspot/vmoptions.jsp

我認為你不能用JNI獲得指向Java堆的指針。 但是,Java堆只是Windows從其中一個進程堆分配給進程的內存。

您可以使用GetProcessHeaps函數( http://msdn.microsoft.com/en-us/library/aa366571(VS.85).aspx )從C ++代碼中獲取進程堆棧,然后使用HeapWalk開始遍歷它們功能。 http://www.abstraction.net/content/articles/analyzing%20the%20heaps%20of%20a%20win32%20process.htm上有一個很好的例子。 您可以通過查找某些字節模式來查明Java堆使用了哪些已分配的塊(JVM源代碼可能會為您提供有關查找內容的一些線索,但祝您好運!)

GC可以隨時移動數據以壓縮內存。 因此,Java堆中的對象沒有固定點。 您可以使用ByteBuffer.allocateDirect()在“C”空間而不是堆中分配內存,並將其固定在內存中。

如果不使用自定義的JVM,我認為沒有辦法滿足您的需求。 理論上你可以使用OpenJDK並對其進行修補或啟用一些跟蹤(不確定是否有符合您需求的跟蹤)。 我認為過程瀏覽器等外部監控工具可以解決您的問題

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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