网易首页 > 网易号 > 正文 申请入驻

Java虚拟机内存区域的划分以及作用详解

0
分享至

  为什么有时候学着学着会突然之间觉得一切都是那么无趣,男的每个月也有那么几天难道?哈哈,不然是什么,我还是要坚持,可以做少一点,但是不能什么都不做。总会过去的,加油

  什么叫运行时数据区呢,看下图就知道了,今天的重点就围绕这张图讲。

  1、程序计数器(寄存器)

  当前线程所执行的字节码行号指示器

  字节码解释器工作依赖计数器控制完成

  通过执行线程行号记录,让线程轮流切换各条线程之间计数器互不影响

  线程私有,生命周期与线程相同,随JVM启动而生,JVM关闭而死

  线程执行Java方法时,记录其正在执行的虚拟机字节码指令地址

  线程执行Nativan方法时,计数器记录为空(Undefined)

  唯一在Java虚拟机规范中没有规定任何OutOfMemoryError情况区域

  在这其中,很多不理解的没关系,我们学过多线程,有两个线程,其中一个线程可以暂停使用,让其他线程运行,然后等自己获得cpu资源时,又能从暂停的地方开始运行,那么为什么能够记住暂停的位置的,这就依靠了程序计数器, 通过这个例子,大概了解一下程序计数器的功能。

  2、本地方法栈

  不知道大家看过源码没有,看过的都应该知道,很多的算法或者一个功能的实现,都被java封装到了本地方法中,程序直接通过调用本地的方法就行了,本地方法栈就是用来存放这种方法的,实现该功能的代码可能是C也可能是C++,反正不一定就是java实现的。

  上面两个不是我们所要学习的重点,接下来三个才是重点。

  3、虚拟机栈

  这个大家都应该有所了解,现在来细讲它,虚拟机栈描述的是Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧用来存放存储局部变量表、操作数表、动态连接、方法出口等信息,每一个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。 这个话怎么理解呢?比如执行一个类(类中有main方法)时,执行到main方法,就会把为main方法创建一个栈帧,然后在加到虚拟机栈中,栈帧中会存放这main方法中的各种局部变量,对象引用等东西。如图

  当在main方法中调用别的方法时,就会有另一个方法的栈帧入虚拟机栈,当该方法调用完了之后,弹栈,然后main方法处于栈顶,就继续执行,直到结束,然后main方法栈帧也弹栈,程序就结束了。总之虚拟机栈中就是有很多个栈帧的入栈出栈,栈帧中存放的都市一些变量名等东西,所以我们平常说栈中存放的是一些局部变量,因为局部变量就是在方法中。也就是在栈帧中,就是这样说过来的。

  以上说的三个都是线程不共享的,也就是这部分内存,每个线程独有,不会让别的线程访问到,接下来的两个就是线程共享了,也就会出现线程安全问题。

  4、堆

  所有线程共享的一块内存区域。Java虚拟机所管理的内存中最大的一块,因为该内存区域的唯一目的就是存放对象实例。几乎所有的对象实例度在这里分配内存,也就是通常我们说的new对象,该对象就会在堆中开辟一块内存来存放对象中的一些信息,比如属性呀什么的。同时堆也是垃圾收集器管理的主要区域。因此很多时候被称为"GC堆",虚拟机的垃圾回收机制等下一篇文章来讲解。 在上一点讲的栈中存放的局部引用变量所指向的大多数度会在堆中存放。

  5、方法区和其中的运行时常量池

  和堆一样,是各个线程共享的内存区域,用于存储已被虚拟机加载的类信息、常量、静态变量、和编译器编译后的代码(也就是存储字节码文件。.class)等数据,这里可以看到常量也会在方法区中,是因为方法区中有一个运行时常量池,为什么叫运行时常量池,因为在编译后期生成的是各种字面量(字面量的意思就是值,比如int i=3,这个3就是字面量的意思)和符号引用,这些是存放在一个叫做常量池(这个常量池是在字节码文件中)的地方,当类加载进入方法区时,就会把该常量池中的内容放入运行时常量池中。这里要注意,运行时常量池和常量池,不要搞混淆了,字节码文件中也有常量池,在后面的章节会详细讲解这个东西。现在只需要知道方法区中有一个运行时常量池,就是用来存放常量的。还有一点,运行时常量池不一定就一定要从字节码常量池中拿取常量,可能在程序运行期间将新的常量放入池中,比如String.intern()方法,这个方法的作用就是:先从方法区的运行时常量池中查找看是否有该值,如果有,则返回该值的引用,如果没有,那么就会将该值加入运行时常量池中。

  平常分析中用到的最多还是堆、虚拟机栈和方法区。

  例如:看下面这段程序,然后画出内存分析图

  最主要是看我的分析过程,这个图由于要显示出动态弹栈画不了,所以只能够那样画一下了。

  1、首先运行程序,Demo1_car.java就会变为Demo1_car.class,将Demo1_car.class加入方法区,检查是否字节码文件常量池中是否有常量值,如果有,那么就加入运行时常量池

  2、遇到main方法,创建一个栈帧,入虚拟机栈,然后开始运行main方法中的程序

  3、Car c1 = new Car(); 第一次遇到Car这个类,所以将Car.java编译为Car.class文件,然后加入方法区,跟第一步一样。然后new Car()。就在堆中创建一块区域,用于存放创建出来的实例对象,地址为0X001.其中有两个属性值 color和num。默认值是null 和 0

  4、然后通过c1这个引用变量去设置color和num的值,

  5、调用run方法,然后会创建一个栈帧,用来装run方法中的局部变量的,入虚拟机栈,run方法中就打印了一句话,结束之后,该栈帧出虚拟机栈。又只剩下main方法这个栈帧了

  6、接着又创建了一个Car对象,所以又在堆中开辟了一块内存,之后就是跟之前的步骤一样了。

  这样就分析结束了,在脑袋中就应该有一个大概的认识对堆、虚拟机栈、和方法区。注意这个方法区的名字,并不是就单单装方法的,能装很多东西。

  这个只是一个简单的分析,可以再讲具体一点,1、创建对象,在堆中开辟内存时是如何分配内存的?2、对象引用是如何找到我们在堆中的对象实例的?通过这两个问题来加深我们的理解。

  1、创建对象,在堆中开辟内存时是如何分配内存的?

  两种方式:指针碰撞和空闲列表。我们具体使用的哪一种,就要看我们虚拟机中使用的是什么了。

  指针碰撞:假设Java堆中内存是绝对规整的,所有用过的内存度放一边,空闲的内存放另一边,中间放着一个指针作为分界点的指示器,所分配内存就仅仅是把哪个指针向空闲空间那边挪动一段与对象大小相等的举例,这种分配方案就叫指针碰撞

  空闲列表:有一个列表,其中记录中哪些内存块有用,在分配的时候从列表中找到一块足够大的空间划分给对象实例,然后更新列表中的记录。这就叫做空闲列表

  2、对象引用是如何找到我们在堆中的对象实例的?

  这个问题也可以称为对象的访问定位问题,也有两种方式。句柄访问和直接指针访问。 画两张图就明白了。

  句柄访问:Java堆中会划分出一块内存来作为句柄池,引用变量中存储的就是对象的句柄地址,而句柄中包含了对象实例数据和类型数据各自的具体地址信息

  解释图:在栈中有一个引用变量指向句柄池中一个句柄的地址,这个句柄又包含了两个地址,一个对象实例数据,一个是对象类型数据(这个在方法区中,因为类字节码文件就放在方法区中),

  直接指针访问:引用变量中存储的就直接是对象地址了,如图所示

  解释:在堆中就不会分句柄池了,直接指向了对象的地址,对象中包含了对象类型数据的地址。

  区别:这两种各有各的优势,使用句柄来访问的最大好处就是引用变量中存储的是稳定的句柄地址,对象被移动(在垃圾收集时移动对象是很普通的行为)时就会改变句柄中实例数据指针,但是引用变量所指向的地址不用改变。

  而使用直接指针访问方式最大的好处就是速度更快,节省了一次指针定位的时间开销,但是在对象被移动时,又需要改变引用变量的地址。在我们上面分析的例子中,就是使用的直接指针访问的方式。

  章来源:公众号:JAVA架构进阶之路,回复“阿里”获取阿里面试官手册

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
米切尔加盟湖人!詹姆斯正式表态,名嘴:NBA最强三巨头出炉

米切尔加盟湖人!詹姆斯正式表态,名嘴:NBA最强三巨头出炉

小豆豆赛事
2024-05-15 15:18:18
对华加征新关税:白宫一拳挥在空气里,图什么?

对华加征新关税:白宫一拳挥在空气里,图什么?

齐鲁壹点
2024-05-15 16:20:43
厉害了!美议员:台海若开战,美90%军机将被解放军按地上摩擦。

厉害了!美议员:台海若开战,美90%军机将被解放军按地上摩擦。

樵山7988
2024-05-15 11:37:14
这一次,“只收钱,但没接受感情”的徐梓钧,“底裤”都被扒光了

这一次,“只收钱,但没接受感情”的徐梓钧,“底裤”都被扒光了

闻星盼夏
2024-05-15 11:15:03
霍兰德示爱火箭被休媒拒绝:更倾向谢泼德 专家晒与库里数据对比

霍兰德示爱火箭被休媒拒绝:更倾向谢泼德 专家晒与库里数据对比

颜小白的篮球梦
2024-05-16 10:33:57
曝偷渡英国“偷图仔”惨死,疑因尿路感染,曾造谣燕郊爆炸因导弹失控

曝偷渡英国“偷图仔”惨死,疑因尿路感染,曾造谣燕郊爆炸因导弹失控

不掉线电波
2024-05-15 10:01:02
逛超市被堵人! MINAMO吓破胆!

逛超市被堵人! MINAMO吓破胆!

孤独的独角兽影视
2024-05-10 11:05:03
掘金从0-2落后到连赢3场做了啥 他们靠的不仅仅是约基奇封神

掘金从0-2落后到连赢3场做了啥 他们靠的不仅仅是约基奇封神

直播吧
2024-05-15 17:08:21
恐怖如斯1月前20球遭帕尔默追平,哈兰德4轮7球终结金靴悬念

恐怖如斯1月前20球遭帕尔默追平,哈兰德4轮7球终结金靴悬念

直播吧
2024-05-15 15:54:17
追梦:森林狼不再相信他们能赢了 这轮系列赛已经结束了

追梦:森林狼不再相信他们能赢了 这轮系列赛已经结束了

直播吧
2024-05-15 15:11:11
朝鲜U17女足主帅:我们看了中国队的比赛,需要准备好对策

朝鲜U17女足主帅:我们看了中国队的比赛,需要准备好对策

懂球帝
2024-05-15 16:48:28
收视率第一!辽篮击败新疆,付豪韩德君爆发,总决赛热度爆棚

收视率第一!辽篮击败新疆,付豪韩德君爆发,总决赛热度爆棚

天涯沦落人
2024-05-15 21:33:41
MSI季中赛:BLG大战GEN,左右手终于交手!G2再战T1

MSI季中赛:BLG大战GEN,左右手终于交手!G2再战T1

落夜电竞
2024-05-15 22:59:25
美女,你的脚虽美,但在动车上也不能这样吧

美女,你的脚虽美,但在动车上也不能这样吧

黄丽搞笑小能手
2024-05-15 16:26:50
他,不再担任江苏省委宣传部部长

他,不再担任江苏省委宣传部部长

创客公社-江苏第一创投媒体
2024-05-15 20:37:45
“迷倒”汪峰的李巧,到底有什么魅力?

“迷倒”汪峰的李巧,到底有什么魅力?

娱乐圈酸柠檬
2024-05-16 07:50:56
俄失踪士兵家属终于爆发了,走上街头呐喊:要么还人,要么给钱!

俄失踪士兵家属终于爆发了,走上街头呐喊:要么还人,要么给钱!

小lu侃侃而谈
2024-05-14 16:18:06
上海知青和藏族卓玛被迫分离,40年后再见,意外得知自己儿孙满堂

上海知青和藏族卓玛被迫分离,40年后再见,意外得知自己儿孙满堂

旧梦初醒已千年
2024-04-12 08:54:40
闹大了!汽车直播间惊现辣眼内容,网友直呼受不了!

闹大了!汽车直播间惊现辣眼内容,网友直呼受不了!

皖声微言
2024-05-15 14:55:06
华为Mate70首发纯血鸿蒙 性能重回第一梯队

华为Mate70首发纯血鸿蒙 性能重回第一梯队

PChome电脑之家
2024-05-16 10:09:14
2024-05-16 11:26:44
Java架构分享
Java架构分享
专注开发,分享心得
276文章数 8894关注度
往期回顾 全部

科技要闻

特斯拉Model Y"孪生兄弟",蔚来新车能行吗

头条要闻

菲律宾"冲闯黄岩岛"的闹剧开场 中国海警已严阵以待

头条要闻

菲律宾"冲闯黄岩岛"的闹剧开场 中国海警已严阵以待

体育要闻

乔丹-贝尔:CBA外援的另一种用法?

娱乐要闻

街头打代驾?李溪芮想翻红那真挺难的

财经要闻

上海家化董事长离职 近四年薪酬约三千万

汽车要闻

标配激光雷达/售24.98万起 问界新M5开启交付

态度原创

数码
时尚
房产
艺术
军事航空

数码要闻

OPPO Enco R3 耳机 5 月 23 日发布,Pad Air2 平板新增极光紫色

入夏当然得穿“裙子”了!40、50岁女人这样穿,一个比一个美

房产要闻

万华“史诗级”交付,给海南楼市上了一课!

艺术要闻

湖山放怀——牛朝山水画作品展 呈现10年间160余幅山水佳作

军事要闻

俄官宣列装“布拉瓦”洲际导弹

无障碍浏览 进入关怀版