内存模型

写这篇开篇的时候,突然想起一件很搞笑的事情。
在今年 3 月份的时候有一场面试。面试官提问,「说一下你对 JAVA 内存模型的了解」,然后我满脑子搜索这是什么?然后我就很尴尬的跟面试官说「提示一下」,面试官提示了「JAVA 内存的堆栈之类的」。

对于 JAVA入门级选手,听过的最多的就是堆和栈了。
「方法在开始运行的时候首先会在内存开辟一个内存空间,叫栈帧,然后压入栈中,运行完之后弹出栈。」这就是我们常常听见的一句话。

今天就来介绍一下内存模型的成员。先上图。
在这里插入图片描述

1.虚拟机栈

虚拟机栈描述的是 Java 方法执行的动态内存模型

栈帧
每个方法执行时,都会创建一个栈帧,伴随着方法从创建到执行完成。
用于存储局部变量表,操作数栈,动态链接,方法出口等。

局部变量表
存储编译期可知的各种基本数据类型,引用类型,returnAddress类型。
局部变量表的内存空间在编译期完成分配,当进入一个方法时,这个方法需要在帧分配多少内存是固定的,在方法运行期间是不会改变局部变量表的大小。

大小
当创建的栈帧超过虚拟机栈大小的时候,会抛出 StackOverflowError。
当创建的栈帧还没有超过虚拟机栈大小的时候,但是超出内存空间,是会抛出 OutOfMemoryError。

---- 补充一下

returnAddress
搜了一下这个关键词,这个关键词是 JVM 的数据类型,唯一个数据类型匹配不到相应的 Java 数据类型。
returnAddress 类型的值指向一条虚拟机指令的操作码。

returnAddress 和 程序计数器的区别
相同点:它们都是记录一个数值。
不同点:程序计数器是用来记录当前栈帧实际执行的行号;returnAddress 是用来记录上个方法执行到的行号;

在这里插入图片描述
举个例子:当进入主程序 main 执行到第 7 行进入 test1 方法,新创建了一个栈帧,程序计数器记录当前 test1 方法运行到哪一行了,里面还有一个 returnAddress 记录了 main 方法执行到第 7 行,用来当 test1 方法执行完的时候可以回到上一层的实际位置。

Java引用类型有哪些
类、数组、接口

Java引用类型有哪几类
强引用:Java 默认是强引用。gc 不会回收这部分内存,即使抛出内存溢出。

剩下三种引用都需要借助 Reference 父类来实现。以下三种都是 Reference 的子类。
软引用(SoftReference):只有当内存不足了才会回收。
弱引用(WeakReference):不管内存是否充足,当发生 gc 就会有可能被回收。
虚引用(PhantomReference):直接将对象创建在待回收的队列里,gc 的时候直接回收。

2.本地方法栈

虚拟机栈为虚拟机执行 Java 方法服务。
本地方法栈为虚拟机执行 native 方法服务。

3.程序计数器

程序计数器是一块较小的内存空间,它可以看作是当前线程(方法)所执行的字节码的行号指示器。
程序计数器处在线程独占区。
如果线程执行的是 Java 方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址。
如果正在执行的是 native 方法,这个计数器的值为 undefined。
此区域是唯一一个在 Java 虚拟机规范中没有规定任何 OutOfMemoryError 情况的区域

4.堆

存放对象实例。
垃圾收集器管理的主要区域。
新生代,老年代,Eden空间。
当内存不足时会抛出 OutOfMemoryError。

5.方法区

存储虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据。
垃圾回收在方法区的行为,当内存不足时会抛出 OutOfMemoryError。

---- 补充一下

4 跟 5 都属于共享数据的区域

在方法区里面会存储类的信息,包括类的版本,字段,方法,接口等。
方法区里面还有一个叫常量池的空间。

在这里插入图片描述
我以前以为 22 行的 str1 的值会是在堆内存中,str1 指向的是堆内存的地址。
现在才知道 “abc” 是常量,存储在方法区内。经常在 String 变量使用 + 的方式,每拼接一次,就产生一个字符串常量。
然后再看 27 行,这种 new 的方式毫无疑问创建在 堆内存中。
再看 31 行,通过 intern 将堆内存空间的对象转移到了方法区,所以堆内存的对象是可以转移到方法区的。

ps: “abc” 是字符串常量,属字节码常量;intern是运行时常量。


好了,内存模型的成员就介绍完了。有什么错的地方还望指出,谢谢。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值