jvm回收方法區


很多人認為方法區(或者HotSpot虛擬機中的永久代)是沒有垃圾收集的,Java虛擬機規范中確實說過可以不要求虛擬機在方法區實現垃圾收集,而且在方法區進行垃圾收集的“性價比”一般比較低:在堆中,尤其是在新生代中,常規應用進行一次垃圾收集一般可以回收70%~95%的空間,而永久代的垃圾收集效率遠低於此。

永久代的垃圾收集主要回收兩部分內容:廢棄常量和無用的類。回收廢棄常量與回收Java堆中的對象非常類似。以常量池中字面量的回收為例,假如一個字符串“abc”已經進入了常量池中,但是當前系統沒有任何一個String對象是叫做“abc”的,換句話說是沒有任何String對象引用常量池中的“abc”常量,也沒有其他地方引用了這個字面量,如果在這時候發生內存回收,而且必要的話,這個“abc”常量就會被系統“請”出常量池。常量池中的其他類(接口)、方法、字段的符號引用也與此類似。

判定一個常量是否是“廢棄常量”比較簡單,而要判定一個類是否是“無用的類”的條件則相對苛刻許多。類需要同時滿足下面3個條件才能算是“無用的類”:

該類所有的實例都已經被回收,也就是Java堆中不存在該類的任何實例。

加載該類的ClassLoader已經被回收。

該類對應的java.lang.Class 對象沒有在任何地方被引用,無法在任何地方通過反射訪問該類的方法。

虛擬機可以對滿足上述3個條件的無用類進行回收,這里說的僅僅是“可以”,而不是和對象一樣,不使用了就必然會回收。是否對類進行回收,HotSpot虛擬機提供了-Xnoclassgc參數進行控制,還可以使用-verbose:class及-XX:+TraceClassLoading、 -XX:+TraceClassUnLoading查看類的加載和卸載信息。

在大量使用反射、動態代理、CGLib等bytecode框架的場景,以及動態生成JSP和OSGi這類頻繁自定義ClassLoader的場景都需要虛擬機具備類卸載的功能,以保證永久代不會溢出。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM