为了账号安全,请及时绑定邮箱和手机立即绑定

死磕JVM-Java内存模型

标签:
Java
Java虚拟机是Java工程师必学的进阶功课,这段时间开始死磕JVM。今天把JVM的基础知识点Java的内存模型怼清楚,废话不多说,干货走起!
图片描述
程序计数器

是什么:程序计数器是很小的一块内存空间,它是当前线程所执行的字节码的行号指示器。

有什么用:解释器通过这个计数器来选取下一条需要执行的字节码指令。
存储什么内容:如果线程执行的是Java方法,存储的是正在执行的虚拟机字节码指令的地址;如果是native方法,计数器值为空(undefined)。

为什么是线程私有的:多线程是线程轮流切换并分配处理器执行时间片的方式来实现的,在任何确定的时刻,一个处理器(对于多核处理器来说就是一个内核)都只会执行一条线程,所以,为了线程在切换后能恢复到正确的执行位置,每个线程应该独立拥有一个程序计数器。

会出现什么异常情况:唯一一个无内存溢出异常的区域。

Java虚拟机栈

是什么:虚拟机栈是Java方法的内存模型,每一个Java方法从调用到执行完成就对应着一个栈帧在虚拟机栈中的入栈和出栈。

存储什么内容:每个方法的执行就会创建一个栈帧,这个栈帧会存储这个Java方法的局部变量表,操作数栈,动态链接,方法出口等信息。

为什么是线程私有的:每个线程所执行的方法可能是不一样的。

会出现什么异常情况:如果线程请求的栈深度>虚拟机允许的深度,抛出栈溢出异常;如果扩展时无法申请到足够的内存,抛出内存溢出异常。

本地方法栈

是什么:本地方法栈的作用和虚拟机栈非常像是,只不过本地方法栈是native方法的内存模型,每一个native方法从调用到执行完成就对应着一个栈帧在本地方法栈中的入栈和出栈。

存储什么内容:同虚拟机栈。

为什么是线程私有的:同虚拟机栈。

会出现什么异常情况:同虚拟机栈。

Java堆

是什么:Java堆是Java虚拟机管理的内存中最大的一块,Java堆是在虚拟机启动的时候创建的。

存储什么内容:存放对象实例,几乎所有的对象实例都在这个内存区域分配内存。

为什么是线程共享的:所有的线程都可以访问不同的对象。其实从内存分配的角度来看,线程共享的Java堆可能其实是多个线程私有的分配缓冲区,不同的线程将各自的对象实例放在看似共享的Java堆的各自的缓冲区上,这样划分可以更好的回收内存,也可以更好点分配内存。

会出现什么异常情况:Java堆可以处于物理上不连续的内存空间上,但逻辑上一定是连续的,在堆中没有内存可以完成对象实例的分配,且无法再扩展时,会抛出内存溢出异常。

方法区

是什么:和堆一样,是各个线程共享的内存区域。很多人把方法区称为永久代,但是本质上这两个不等价,Java虚拟机将GC分代收集扩展至方法区,使用永久代来实现方法区,这样GC收集器就能像管理Java堆一样管理方法区而不需要再写一套GC收集来管理方法区。当然在方法区里也可以设置不进行GC收集。

存储什么内容:已被虚拟机加载的类信息,类常量,类的静态变量,即时编译器编译后的代码等。运行时常量池也是方法区的一部分。

为什么是线程共享的:各个线程都可以访问虚拟机加载的类。

会出现什么异常情况:内存溢出异常。

直接内存

是什么:直接内存并不是虚拟机运行时数据区的一部分,也不是Java虚拟机定义的内存区域,但也经常被使用。JDK1.4加入了NIO类,一种基于通道与缓冲区的新I/O方式,NIO可以使用native函数库直接分配堆外内存,然后通过一个存储在Java堆中的DirectByteBuffer对象作为直接内存的引用来操作直接内存,这样可以避免在Java堆和native堆来回复制数据,从而提高了性能。

会出现什么异常情况:受机器总内存的影响,会出现内存溢出异常。

点击查看更多内容
22人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
算法工程师
手记
粉丝
1533
获赞与收藏
2735

关注作者,订阅最新文章

阅读免费教程

感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消