方法区元空间实现之jdk7和8字符串常量池、运行时常量池、静态变量到底在哪?
方法區(落地實現jdk7永久代,jdk8元空間),元空間并不在虛擬機中,而是使用本地內存,它和堆在邏輯上是連續的,但在物理上是不連續的,所以也叫非堆。
1、此區域是線程共享的。儲存已加載的類型信息、常量、靜態變量、即時編譯器編譯后的代碼等數據;
2、常量池:編譯器生成的各種字面量和符號引用;
3、關于字符串常量池和運行時常量池的位置說明:
| jdk1.6 | 永久代 | 字符串常量池、運行時常量池、靜態變量都是在永久代中 |
| jdk1.7 | 永久代 | 字符串常量池和靜態變量被移動到了堆當中,運行時常量池還是在永久代中 |
| jdk1.8 | 元空間 | 字符串常量池和靜態變量仍然在堆當中;運行時常量池、類型信息、常量、字段、方法被移動都了元空間中 |
4、元空間的好處:
① 減少報OOM的可能:元空間與永久代類似,本質區別是元空間并不占用虛擬機內存了,而是使用本地內存,由于本地內存一般是比較大的,所以方法區就沒有那么容易報OOM(OutOfMemoryError)。
② 提高JVM性能:元空間的垃圾回收很少,一定程度上減少了GC掃描及壓縮的時間。
③類及相關的元數據的生命周期與類加載器的一致;
④ 每個加載器有專門的存儲空間。
元空間的對象被垃圾回收的概率相對堆空間的對象是要小很多的,所有將兩者分開,就減少了很多去掃描元空間對象帶來的開銷。
5、字符串常量池為什么要移動到堆空間中?
個人的理解:對于字符串常量這種創建完成用幾次就不被使用的對象,是很容易被回收的。而要進行頻繁垃圾回收的地方是堆空間, 這樣在JDK7就把字符串常量池移動到堆空間中就是很明智和有必要的選擇了。這樣就避免了放到不頻繁進行垃圾回收的元空間中應該被垃圾回收的對象而不能及時進行垃圾回收的浪費空間的現象出現。
思考:那么靜態變量為什么也要在JDK7和字符串常量池一起移動到堆空間中呢?靜態變量是不是和類一樣的生命周期嗎?
尚硅谷深解Java虛擬機(JVM)內存結構各部分總結【三層劃分】https://blog.csdn.net/qq_43012792/article/details/107358550
總結
以上是生活随笔為你收集整理的方法区元空间实现之jdk7和8字符串常量池、运行时常量池、静态变量到底在哪?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: rust-let 不可变绑定与可变绑定(
- 下一篇: cuda-gpu计算随笔(1)