簡體   English   中英

強制JVM釋放內存

[英]Force JVM to free memory

我改進了我的代碼,以便從垃圾收集器中獲得更好的結果。

現在,當我調用System.gc()它釋放所有內存。 但是當我在不調用System.gc()的情況下觀察內存使用情況時,應用程序會保留並使用越來越多的內存。

這是否意味着我的改進正在發揮作用,我的所有引用都是正確的,我可以忽略JVM如何自行釋放內存。 或者我的代碼中是否存在另一個問題,即JVM在不運行垃圾收集器的情況下保留更多內存的原因。

取決於您的JVM使用哪個GC。 如果它是JDK9那么它可能是G1,它在內存消耗方面是“貪婪”的,所以根據你檢查內存使用的方式,它看起來好像占用了大量的內存(在這里保留它並動態/按需使用/釋放。

您可以使用

https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstat.html

檢查內存消耗。

至於GC和內存消耗分析,請查看以下內容: G1垃圾收集器的高內存使用問題 + https://www.javacodegeeks.com/2017/11/minimize-java-memory-usage-right-garbage-collector.html

未使用的內存浪費了內存。

為什么要顯式調用System.gc() 恕我直言,你永遠不應該調用它並將其留給JVM來決定何時運行GC。 (如果你是新手JVM可以比你更好的決策。調用System.gc() ,只有當你真的知道自己在做什么。)這通常是一個不好的做法來調用System.gc()

System.gc()只是JVM運行GC的請求/提示。 它絕不意味着GC肯定會運行。

您可以在Java中使用內存泄漏,但這肯定不是您在案例中要查看的內容,因為正如您在調用System.gc()時提到的那樣,您可以看到一些內存被釋放。 (因此,您仍然不能保留未使用對象的引用,這可能會阻止GC清理這些對象。)

為什么你認為這是你的代碼的問題? 可能的情況是不需要進一步的內存或者需要內存,你已經有足夠的內存(並且以外行的話說,GC不會釋放內存,因為程序運行還有很多 - 那么GC為什么要打擾內存?)

沒有辦法強制JVM釋放內存, System.gc()只是一個提示。 由GC來管理內存(注意有各種類型的內存,例如堆,元空間,堆外)。 每個GC算法都有多個配置參數可供您調整,但兩者都不會為您提供按需釋放內存的選項。

JVM在啟動時保留內存,並從操作系統請求額外的內存,直到達到配置的任何限制。 它以塊增量執行,一次請求MB或更多內存,因為從字節逐字節地請求內存將是非常低效的。

當然有可能存在內存泄漏,這意味着您的程序在不釋放內存的情況下不斷分配內存。 (例如,在不斷增長的列表或地圖中。)您將需要一個內存分析器,以確保您沒有遭受這種情況。

除此之外,我不擔心虛擬機是否會在不釋放內存的情況下繼續分配內存。 這就是現代虛擬機的工作方式,特別是在“客戶端”模式下:只要有足夠的可用內存,它們就不會浪費時間進行垃圾收集。 如果接近內存限制,那就是垃圾收集器啟動的時間。 (“客戶端”與“服務器”模式是一個JVM參數,如果需要,可以試用它,更多信息: “java -server”和“java -client”之間的真正區別?

除此之外,你可以做的是:

a)確保執行完整GC的機制實際上是執行完整的GC。 我所知道的最好的機制(不能保證工作,但它似乎可以工作)就是分配一個僅通過軟引用引用的對象,然后繼續調用GC直到軟引用變為null 。

b)在調試運行時(例如,如果啟用了斷言),每隔幾秒就在一個單獨的線程上繼續觸發一個完整的GC。 然后,如果你查看VM消耗的內存,它應該保持大致不變。 如果沒有,你有內存泄漏。

暫無
暫無

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

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