JVM介绍篇一:JVM运行时数据区域看这篇就够了

csdn中看到了很多关于JVM运行时数据区域介绍的,但是并没有看到什么讲解很好的资料
所以这里自己写一个记录下,方便日后工作中需要时可以查阅

运行时数据区域

Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这些区域各有各的用途,有的区域随着虚拟机的启动而启动,有的依赖用户线程的启动和结束而建立和销毁。
主要包括:程序计数器,Java虚拟机栈,本地方法栈,Java堆,方法区

网上的图,红色框里框多了

在这里插入图片描述

程序计数器

程序计数器是当前线程所执行程序字节码的行号计数器,字节码解释器根据这个程序计数器的值来选取下一条需要执行的字节码,实现程序的分支、循环、跳转、异常处理 和线程控制等基本功能
在java中,每个线程的执行都需要操作系统轮换的分配CPU处理器,因此每个线程都有自己的程序计数器,各个线程之间的计数器互不影响,独立存储,计数器占用空间不大。因此计数器是线程私有的内存。当线程正在执行java方法时,计数器的值为当前字节码指令的地址。当执行的是本地方法是,计数器的值为空。计数器是唯一一个不会发生OOM的数据区域

Java虚拟机栈

虚拟机栈也是线程私有的,它的生命周期和线程相同。虚拟机栈是java方法执行的内存描述:每一个方法的执行都会为其创建一个栈帧栈帧用于存储局部变量表,操作数栈,动态链接和方法的出口信息
局部变量表存储了编译期可知的基本数据类型[byte,int,float,double,char,short,long,boolean],对象引用类型(不是实际的对象,可能只是对象的内存地址),动态返回地址(Return Address) ,进入一个方法后,局部变量表的内存空间在编译后是完全确认的,方法运行期间不会改变其大小。每一个方法从调用到执行完成,都对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。

该区域可能有两类异常:StackOverflowError:线程请求的深度大于虚拟机允许的深度;OutOfMemory:如果虚拟机栈可以动态扩展,但是扩展的时候无法申请到足够的内存。

本地方法栈

与java虚拟机栈类似也是线程私有的,但是不同的是Java虚拟机栈是为java方法服务(字节码),本地方法栈是为非java语言但是虚拟机又使用到的方法服务的(比如类加载器中最顶层的实现使用的是c++)。同样的,本地方法栈也会抛出StackOverflowError和OutOfMemory异常。

java堆

java堆是被所有线程共享的一大片内存区域,是被所有线程共享的其作用就是为创建的实例对象或者数组分配内存也因此java堆是GC的主要针对区域

Java堆是垃圾收集器管理的内存区域,由于现代收集器基本都是基于分代收集理论设计的,所以把java堆内存分为不同的区域:新生代(Eden区,From Survivor区,To Survivor),老年代。但是无论java堆内存从什么角度被怎么划分,在这java堆中存放实例对象或者数组这一事实无法更改。进一步划分的目的是为了更加高效滴利用这一内存中的宝地罢了。根据规范,java堆的内存在物理上不要求连续,只要逻辑上连续就好了。

该区域可能抛出的异常:OutOfMemory:堆中没有内存足以给实例分配,并且堆也无法再扩展了

方法区

与java堆一样,也是线程共享的内存区域,主要用于存放已经被虚拟机加载的类型信息,常量,静态变量,以及实时编译的数据。虽然我们很不愿意把方法区和java堆混为一谈,但是从GC的角度,GC就是将方法区看成是java堆的永久代。
这里需要注意的是JDK1.8完全废弃了永久代的概念,改用本地内存中实现的元空间来代替,所以方法区现在应该也叫做元空间。
运行时常量池属于方法区的一部分。java文件编译的Class文件中,除了类的基本信息(版本,字段,方法,接口等)之外,还有就是常量池,用于存放编译期间生成的字面量和符号引用,这部分内容在类被加载后就被放入运行时常量池了。
虽然GC在这“元空间”上的效果总不是那么理想,但是却必不可少,GC在元空间的目的是针对常量池的回收以及类型卸载。
该区域可能抛出的异常:OutOfMemory:方法区没有内存足以分配时出现,也就是本地内存满了的情况

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JVM运行区域是指JVM运行Java程序所划分的内存区域,主要分为以下几个部分: 1. 程序计数器:程序计数器是一块较小的内存区域,可以看作是当前线程所执行的字节码的行号指示器。每个线程都有一个独立的程序计数器,线程私有。当线程执行Java方法,程序计数器记录的是正在执行的虚拟机字节码指令地址;当线程执行本地方法,程序计数器值为空(Undefined)。 2. Java虚拟机栈:Java虚拟机栈也是线程私有的,它的生命周期与线程相同。Java虚拟机栈描述的是Java方法执行的内存模型:每个方法执行都会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每个方法从调用直至执行完毕的过程,对应着一个栈帧在Java虚拟机栈中从入栈到出栈的过程。 3. 本地方法栈:本地方法栈与Java虚拟机栈类似,只不过它为本地方法服务。也是线程私有的。HotSpot虚拟机将其实现为虚拟机调用Native方法的接口。 4. Java堆:Java堆是Java虚拟机所管理的内存中最大的一块,也是被所有线程共享的一块内存区域,用于存放对象实例。Java堆是垃圾收集器管理的主要区域,因此也被称作“GC堆”。 5. 方法区:方法区也是被所有线程共享的一块内存区域,用于存储已被虚拟机加载的类信息、常量、静态变量、即编译器编译后的代码等数据。 6. 运行常量池:运行常量池是方法区的一部分,用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行常量池中。 7. 直接内存:直接内存并不是JVM运行数据区的一部分,也不是Java虚拟机规范中定义的内存区域。在JDK1.4中,引入了NIO类,可以使用Java程序直接向操作系统申请一块内存区域,这块内存区域不受JVM管理,也不受Java虚拟机规范的限制,不需要进行垃圾回收。这种内存区域称为直接内存,可以提高系统的性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值