死磕P7: JVM内存划分必知必会(一)

这是「死磕P7」系列第 001 篇文章,欢迎大家来跟我一起 死磕 100 天,争取在 2025 年来临之际,给自己一个交代。

JVM 内存区域划分是面试常考点,属于死记硬背型,比较让人头大的是不同版本的 JDK 具有不同的划分方式,主要矛盾点就来自 方法区,永久代,元空间 这几个破玩意。

整理了一些个人觉得比较靠谱的资料,进行了一些汇总,第一方便自己记忆,第二也希望大家不要再为内存区域划分的面试而苦恼。

虚拟机规范定义

先来看一下《Java 虚拟机规范》定义的概念,规范和具体实现是两回事,可以理解为规范是接口定义,具体的虚拟机实现是接口的实现类,实现细节千差万别,如 HotSpot VM, JRockit VM, Graal VM 等等(这些知道一下就好)。

程序计数器,虚拟机栈,本地方法栈基本没啥争议点,也比较好记,并且他们是属于线程隔离的(线程独享,一人一杯奶茶,各喝各的)

主要容易搞混的是 方法区 和 堆,究其原因其实就是因为版本更新导致的,一般大家说的都是 HotSpot VM, 下面用图示的方式告诉您不同版本的区别是什么。

JDK 1.6 内存划分

JDK 1.6 JVM 运行时内存就分为方法区(也叫永久代),堆,虚拟机栈,本地方法栈,程序计数器

JDK 1.7 内存划分

JDK 1.7 中将方法区中的字符串常量池和静态变量等存储区域调整到了堆中,方法区中只保留了类型信息,划分区域仍然是方法区(也叫永久代),堆,虚拟机栈,本地方法栈,程序计数器,唯一的区别就是方法区里面放置的内容减少了,如下图

JDK 1.8 内存划分

JDK 1.8 中将方法区直接移出了 JVM 内存,直接放置到了 物理内存 中,并且改名叫元空间(Meta Space),也就没有了永久代的叫法(当然,你要称元空间就是永久代也不算错,就好比你小时候一直被大家叫:狗蛋,长大了回老家,老同学还这么叫你一样,哈哈)

为什么做这些改动?

大概了解一点就行,我们又不是设计开发 JVM 的,别人给我们啥就用啥好了!

原因大概有以下几点:

  • Oracle 收购了两种 JVM:HotSpot VM 和 JRockit VM,并且想要将它们整合,但二者方法区实现差异较大;

  • 字符串存在永久代中,容易出现性能问题和 OOM;

  • 类及方法的信息大小较难确定,永久代大小难以确定:太小易导致永久代溢出,太大则易导致老年代溢出(JVM 内存是有限的,此消彼长);

  • 永久代会为垃圾回收带来不必要的复杂度,且回收效率较低(性价比低)。

总结

JVM 内存划分一直都是考点,当然考得不仅仅是上面简单的怎么划分的,今天主要让大家彻底搞懂不同版本 JVM 之间的划分差异,做到了然于胸,不再为网上的乱七八糟的文章所困惑(感觉大家写的又对又不对,比较乱)。

下一篇我们会继续解读 JVM 的内存划分,主要介绍各区域的一些特点。

如果大家对技术感兴趣,欢迎大家链接我,一起拉个小群技术交流,一起成长。

小福利

文末小福利,作为资深囤货达人,购置或转存了上千 T 的各种资源,反正我也学不完,如有需要,可以公号: 新质程序猿 找到我,直接送您,能帮助到大家也算是有所福报吧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值