簡體   English   中英

堆轉儲!=虛擬內存?

[英]Heap dump != virtual memory?

並不真正了解Java,尤其是Java調試,但是在Jenkins中使用Monitoring進行堆轉儲,然后在Eclipse中使用MAT對其進行解碼,顯示總內存使用了169.4 MB,而在Jenkins中,監視內存似乎經常使用很多和GC頻繁運行。 -XmX是4G。

為何只有MAT獲得169.4 MB? 可能是因為在進行轉儲之前,詹金斯執行了GC嗎? 如果是這樣,是否可以避免看到完整的內存轉儲?

了解記憶

是的,Java堆轉儲和虛擬內存轉儲(在Windows中稱為“崩潰轉儲”或“內存轉儲”)是不同的。

Java堆轉儲僅包含與Java相關的內存,即Java對象所在的位置。 Java堆轉儲使用諸如MAT(如您所述)之類的工具Java Heap Analysis Tool進行分析。

Windows(用戶模式)進程的故障轉儲包含所有虛擬內存,其中虛擬內存是提供內存的操作系統的術語。 在Windows上,這是通過VirtualAlloc分配的所有內存。

操作系統虛擬內存將包括 Java堆,因為Java只能從操作系統請求內存。

因此,在比較內存大小時,重要的是要了解該工具是Java專用還是OS通用的。

在您的情況下, Monitoring很像一個通用工具,因為它處理的是進程列表和CPU時間,似乎沒有什么是Java特定的。 另一方面,從其描述來看, MAT顯然是一種Java工具。

記憶差異

那么Java堆大小與虛擬內存大小有多少不同?

許多:

  1. 加載的EXE / DLL帳戶到虛擬內存,而不是Java堆
  2. 本機代碼使用的內存(例如,通過JNI)占用虛擬內存,而不占用Java堆
  3. Java從操作系統請求的內存,但是Java尚未使用的內存,肯定是虛擬內存,但是從Java角度來看,它可以報告為“免費”。

顯然,收集堆轉儲的工具會執行GC以減小轉儲的大小。 由於可以被GC化的東西不應該產生OOM,因此它的目的是發現內存泄漏而不是對內存使用進行故障排除。

VM請求虛擬內存以存儲各種數據。 然后,VM分配一些內存來存儲變量(即堆),本機代碼(非堆),保留一些尚未使用的內存。 結果,虛擬內存嚴格大於堆。 假設您可以編寫簡單的無限遞歸(堆將幾乎與虛擬內存一樣大)或在hello world程序中加載大dll(堆比虛擬內存小得多),則堆與虛擬內存之間沒有明確的關聯。 )。

暫無
暫無

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

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