JVM運行時區域各線程共享的區域包括堆區和方法區。
堆區
堆區最最主要的功能是存儲對象實例【上篇也提到過】,因此Java垃圾回收的主要戰場就是在堆區,因此也有稱為GC堆區。如果堆區的內存不夠會出現OutOfMemory異常。
為了方便回收,堆區可以細分為新生代和老年代。顧名思義,新生代里都是新創建的或者年齡不大的對象,新生代區又有三個區域,eden區,s0區和s1區。絕大多數情況新生對象都是在eden區,當一次回收之后如果對象還存在,就會進入s0或者s1區,之后每次回收如果都能存在,那么年紀就加一,達到一定年齡后就會進入老年代區。
老年代區存儲的都是經過很多次回收仍然存在的,也有一些大的對象會直接進入老年代【比如長字符串和長數組】,表示這里對象存活率高,聲明周期長。老年代和新生代區域的差別在於新生代GC次數更加頻繁。
方法區
在不同的JDK版本和不同的JVM實現方式中,方法區的實現方法多經變更,甚至互相矛盾,例如永久代和元空間,因此很難詳細的總結方法區的具體工作方式。因此,了解方法區的主要存儲對象是更為重要的,包括:
1、類型信息:
類的完整名稱
類的直接父類的完整名稱
類的直接實現接口的有序列表
類型標志(類類型還是接口類型)
類的修飾符(public private defautl abstract final static)
2、類型的常量池
存放該類型所用到的常量的有序集合,包括直接常量(字符串、整數、浮點數)和對其他類型、字段、方法的符號引用。
3、字段信息(該類聲明的所有字段)
字段修飾符(public、peotect、private、default)
字段的類型
字段名稱
4、方法信息
方法信息中包含類的所有方法。
方法修飾符
方法返回類型
方法名
方法參數個數、類型、順序等
方法字節碼
操作數棧和該方法在棧幀中的局部變量區大小
異常表
5、類變量(靜態變量)
6、指向類加載器的引用
7、指向Class實例的引用
8、方法表
9、運行時常量池(Runtime Constant Pool)
方法區存儲內容轉載自這里
總結:堆區用於存儲實例對象,GC過程在此發生;方法區存儲很多東西,重要的包括常量池、靜態變量以及一些類和方法信息;棧區存儲方法的參數和局部變量,還有基本數據類型和引用類型的引用。
