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

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.

相关推荐
热点推荐
胡锡进反击?“毛星火”大小号惨遭封禁!如何生存成难题!

胡锡进反击?“毛星火”大小号惨遭封禁!如何生存成难题!

白沙巷
2024-04-29 10:24:35
童瑶这腿上这么多妊娠纹,女人味真足

童瑶这腿上这么多妊娠纹,女人味真足

室内设计师阿喇
2024-04-28 16:45:22
特斯拉通过汽车数据安全4项全部要求,各地对特斯拉使用限制已陆续取消

特斯拉通过汽车数据安全4项全部要求,各地对特斯拉使用限制已陆续取消

澎湃新闻
2024-04-28 22:48:28
刚刚!江西籍演员刘涛上热搜了!

刚刚!江西籍演员刘涛上热搜了!

阿芒娱乐说
2024-04-28 18:13:07
几乎全是假货,利润率高达650%,为何很多人仍然愿意被割韭菜!

几乎全是假货,利润率高达650%,为何很多人仍然愿意被割韭菜!

盛世科记
2024-04-21 10:00:48
沃格尔季后赛遭7连败 此前3场失利是2020-21赛季率领湖人不敌太阳

沃格尔季后赛遭7连败 此前3场失利是2020-21赛季率领湖人不敌太阳

直播吧
2024-04-29 13:36:17
“求饶”已经来不及了,俄军起飞2架轰炸机,中国邻国恐将遭殃

“求饶”已经来不及了,俄军起飞2架轰炸机,中国邻国恐将遭殃

星辰故事屋
2024-04-28 19:15:12
郭士强加盟,孙铭徽不走+强援加盟

郭士强加盟,孙铭徽不走+强援加盟

元爸体育
2024-04-28 16:31:43
1986年,邓小平就三个城市征求作为谭启龙的养老地,谭一个都不选

1986年,邓小平就三个城市征求作为谭启龙的养老地,谭一个都不选

冰点历史
2024-04-29 10:05:20
田馥甄年收入仅剩2000万台币左右!怪不得不肯放弃内地市场

田馥甄年收入仅剩2000万台币左右!怪不得不肯放弃内地市场

金牌娱乐
2024-04-28 10:18:15
俄媒:前线形势严峻,乌克兰武装部队总司令承认乌军“战术性”撤退

俄媒:前线形势严峻,乌克兰武装部队总司令承认乌军“战术性”撤退

环球网资讯
2024-04-29 11:10:18
梁洛施接儿子放学!2年生3胎仍嫩似高中生,不嫁豪门却比豪门潇洒

梁洛施接儿子放学!2年生3胎仍嫩似高中生,不嫁豪门却比豪门潇洒

顶牌故事会
2024-04-28 10:54:59
俄乌战争一年后,才知毛主席1957年的预言精准无误,令人十分感叹

俄乌战争一年后,才知毛主席1957年的预言精准无误,令人十分感叹

平安是福呀
2023-12-19 20:07:03
东莞放大招!几乎完全放开入户政策,网友:东莞的繁荣又要回来了

东莞放大招!几乎完全放开入户政策,网友:东莞的繁荣又要回来了

火山诗话
2024-04-29 09:14:13
“儿子”是一线明星,女儿是奥运冠军,可55岁的她才是人生赢家

“儿子”是一线明星,女儿是奥运冠军,可55岁的她才是人生赢家

清欢渡语
2024-04-25 21:50:38
纳达尔今日赛程!女单八强全部产生!中国三花出战!张之臻排名恐再降!

纳达尔今日赛程!女单八强全部产生!中国三花出战!张之臻排名恐再降!

小豆豆赛事
2024-04-29 12:10:51
美媒:查尔斯三世健康状况不佳,葬礼计划定期更新

美媒:查尔斯三世健康状况不佳,葬礼计划定期更新

参考消息
2024-04-28 12:12:25
500万黑人又“黑化”一座城,黑人新生儿占了6成,大街上随处可见

500万黑人又“黑化”一座城,黑人新生儿占了6成,大街上随处可见

零点历史说
2024-04-25 11:28:46
不让碰?男子出差一个月,回来发现老婆不让碰,网友:这眼神吓人

不让碰?男子出差一个月,回来发现老婆不让碰,网友:这眼神吓人

雅清故事汇
2024-04-16 11:14:39
广东被撤销的直辖市:GDP已超3万亿,未来会重新直辖吗?

广东被撤销的直辖市:GDP已超3万亿,未来会重新直辖吗?

小小包工头阿汾
2024-04-29 01:09:07
2024-04-29 14:14:44
Java架构分享
Java架构分享
专注开发,分享心得
276文章数 8894关注度
往期回顾 全部

科技要闻

马斯克想把特斯拉中国数据送出国 这事太难

头条要闻

睡实验室门口学者再晒照 质疑单位对其意见"已读不回"

头条要闻

睡实验室门口学者再晒照 质疑单位对其意见"已读不回"

体育要闻

湖人的G4,尽人事得到了回报

娱乐要闻

田馥甄遭抵制,蔡依林却能稳稳捞金?

财经要闻

问界M7追尾起火3人遇难 四大疑问待解

汽车要闻

配置更丰富 静态体验2024款欧拉好猫

态度原创

教育
艺术
数码
本地
旅游

教育要闻

看来还是我表达方式有问题……还有人听不懂!

艺术要闻

共度北京108小时 北京当代2024“凝聚”全球36座城市100余家艺术机构

数码要闻

小米米家风扇灯42英寸上架:定制全光谱灯珠/自然风感,549元

本地新闻

云游中国|苗族蜡染:九黎城的“潮”文化

旅游要闻

入境游热度持续攀升 “畅游中国”更便捷

无障碍浏览 进入关怀版