JVM内存模型详解(1.7与1.8的区别)[通俗易懂]

JVM内存模型详解(1.7与1.8的区别)[通俗易懂]文章目录1.JDK、JRE、JVM关系2.JAVA程序的运行(为什么java可以跨平台)3.JVM运行时数据区1.JDK、JRE、JVM关系从图中就可以很清晰的看清他们之间的关系:JDK>JRE>JVM2.JAVA程序的运行(为什么java可以跨平台)比如我们编写一个HelloWord.java,他是如何运行的呢因为有JVM,所以我们在不同平台只需要下载对应的JDK即可…

大家好,又见面了,我是你们的朋友全栈君。

1.JDK、JRE、JVM关系

在这里插入图片描述
从图中就可以很清晰的看清他们之间的关系:JDK>JRE>JVM

2.JAVA程序的运行(为什么java可以跨平台)

比如我们编写一个HelloWord.java ,他是如何运行的呢
在这里插入图片描述
因为有JVM,所以我们在不同平台只需要下载对应的JDK即可

3.JVM运行时数据区

JVM内存模型详解(1.7与1.8的区别)[通俗易懂]
JVM内存模型详解(1.7与1.8的区别)[通俗易懂]

其中对于方法区,很多人更愿意称为:“永久代(Permanent Generation)”,不过本质上两者并不等价,仅仅是因为习惯使用HotSpot虚拟机的设计团队选择吧GC分代收集扩展至方法区,或者说使用永久代来实现方法区而已,这样HotSpot的垃圾收集器就可以像管理Java堆一样管理这部分内存,能够省去专门为方法区变编写内存管理代码的工作。不过对于其他虚拟机(如BEA JRockit、IBM J9等)来说并不存在永久代的概念
这是jdk1.8之前的内存模型,其中方法区和堆是是线程共享的,但是在jdk1.8之后
元数据区取代了永久代。元空间的本质和永久代类似,都是对JVM规范中方法区的实现。不过元空间与永久代之间最大的区别在于:元数据空间并不在虚拟机中,而是使用本地内存
JVM内存模型详解(1.7与1.8的区别)[通俗易懂]

程序计数器(Program Counter Register):

  它是一块较小的内存空间,可以看做是指向当前线程所执行的字节码的行号指示器。在虚拟机的概念模型里(仅是概念模型,各种虚拟机可能会通过一些更高效的方式去实现),字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程回复等基础功能都需要依赖计数器来完成()。

为什么程序计数器为线程私有呢?

 由于java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器(对于多核处理器来说是一个内核)都只会执行一条线程中的指令,因此,为了线程切换后能恢复到正常的执行位置,每条线程都需要一个独立的程序计数器,各线程之间计数器互不影响,独立存储,为线程私有的内存。

程序计数器值的问题

 如果线程正在执行的是一个java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是Native方法,这个计数器的值则为空(Undefined)。此内存区域是唯一一个在java虚拟机规范中没有规定任何OutOfMemoryError情况的区域

Java虚拟机栈(Java Virtual Machine Stacks)

 java虚拟机栈与程序计数器一样,也是线程私有的,他的生命周期和线程保持一致。他是存储当前线程运行方法时所需要的数据、指令、返回地址。在每个方法执行时,虚拟机栈都会创建一个栈帧(Stack Frame),用于存储:局部变量表、操作数栈、动态链接、方法出口等信息。如下图:
在这里插入图片描述

 其中局部变量表存放了编译器可知的各种基本数据类型(boolean、byte、char、short、int、float、long、double)、对象引用(reference类型,它不等同与对象本身,可能是一个指向对象其实地址的引用指针,也可能是指向一个代表对象的句柄或其他与此对象相关的位置) 和returnAddress类型(指向了一条字节码指令的地址)

 局部变量表的存储空间是32位,刚好可以放一个int类型,所以长度为64为的long和double类型的数据会占用2个局部变量空间(Slot),局部变量表的大小在编译器就已经确定了

 在java虚拟机规范中,对java虚拟机栈规定了两种异常状况:如果线程请求的栈深度大于虚拟机所允许的深度,将会抛出StackOverflowError异常;如果虚拟机栈可以动态扩展(当前大部分虚拟机都可以动态扩展,只不过ava虚拟机规范中也允许固定长度的虚拟机栈),扩展时无法申请到足够的内存,就会抛出OutOfMemoryError异常

本地方法栈(Native Method Stack)

本地方法栈和虚拟机栈所发挥的作用非常相似,区别就是:

  • java虚拟机栈为虚拟机执行java方法(也就是字节码)服务
  • 本地方法栈为虚拟机使用到的Native方法服务

堆(Heap)

在这里插入图片描述
 在 Java 中,堆被划分成两个不同的区域:新生代 ( Young )、老年代 ( Old )。新生代 ( Young ) 又被划分为三个区域:Eden、From Survivor、To Survivor,这样划分的目的是为了使 JVM 能够更好的管理堆内存中的对象,包括内存的分配以及回收。java堆是java虚拟机管理的内存中最大的一块,java堆是被所有线程共享的一块内存区域,堆的唯一目的就是存放实例对象,几乎所有的对象实例都在这里分配内存。
 java堆可以处于物理上不连续的内存空间中,只要逻辑上是连续的即可,就像我们磁盘空间一样。(不过在实现中既可以大小固定,也可以是可扩展,通过-Xmx 和-Xms控制),如果在堆中没有内存完成实例分配,并且堆也无法再扩展时,将会抛出OutOfMemoryError异常

方法区(Method Area)

  方法区和堆一样,是各个线程共享的区域,用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码数据等
ps:方法区中还包括运行时常量池(Runtime Constant Pool),Class文件除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池(Constant Pool Tabel),用于存放编译期生成的各种字面量常量和符号引用,这部分内容将在类加载后进入方法区的运行时常量中存放,当常量池无法再申请到内存时也会抛出OutOfMemoryError异常

关于我

觉得文章不错请扫码关注我吧

weichat

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/145972.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • sqlyog安装详细步骤

    sqlyog安装详细步骤mysql安装步骤请点击:Mysql5.6安装详细步骤我的sqlyog百度云链接(永久有效):http://pan.baidu.com/s/1i5j4GG9密码获取请点击:获取密码注册码序列号(Code):8d8120df-a5c3-4989-8f47-5afc79c56e7c如果使用sqlyog登陆报错的话请参考https://bl…

  • 怎么更改wifi频段_TP-Link无线路由器怎么修改无线信道和频段「建议收藏」

    怎么更改wifi频段_TP-Link无线路由器怎么修改无线信道和频段「建议收藏」有时候为了减少WiFi信道干扰,我们会修改一下路由器的信号频段,下面本文以TPLinkTL-WDR6300无线路由器为例,教大家如何改无线改信号频段,以下是具体的设置教程。改路由器信号频段可以在电脑或手机中完成,修改比较简单,下面以PC为例,手机上也是一样的,借助浏览器就可以完成操作。1、首先打开浏览器,然后输入TPLink路由器管理员登录地址:tplogin.cn(也可以是192.168….

  • playbook安装docker

    playbook安装docker

  • css 去色_css按钮点击改变颜色

    css 去色_css按钮点击改变颜色有这么一个样式,可以在你实现无色和加色之间游刃有余。网站设计师在设计网页时,有时将一块图片设计成灰色,鼠标移上去,图片就有颜色。一般的逻辑是做两张图片,然后在鼠标上做图片切换事件。当然这种方法可以完美是实现, 不过有个小瑕疵,就是你要切一倍的图片(有色+无色)。下面介绍样式实现,可以减少一倍量的工作哦。//HTMLCSS.grayscaleimg{filter:g

  • sublime 激活码【2021.7最新】

    (sublime 激活码)这是一篇idea技术相关文章,由全栈君为大家提供,主要知识点是关于2021JetBrains全家桶永久激活码的内容IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.cn/100143.htmlTR0LFTT656-eyJsaWN…

  • Page.RegisterStartupScript 的用法

    Page.RegisterStartupScript 的用法轉自:http://www.cnblogs.com/jxyxhz/archive/2008/11/25/1340432.htmlPage_load调用JS函数以及confirm的用法protectedvoidPage_Load(objectsender,EventArgse)   {       if(!IsPostBack)       {    

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号