位置:首页 > 后端 > java

Java虚拟机(1)JVM内存区域划分及相关概念

chenlong 发布:2021-08-28 22:15:42阅读:

1、JVM内存区域划分(程序计数器、java堆、java虚拟机栈、本地方法栈、方法区)

  • 程序计数器

  1. 一块较小的内存空间,它的作用可以看作是当前线程所执行的字节码的行号指示器。

  2. 如果线程正在执行的是一个java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是Native方法,这个计数器值则为空。

  3. 此内存区域是唯一一个在java虚拟机规范中没有规定任何OutOfMemoryError情况的区域。

  • java堆(线程共有)

  1. 全局共享

  2. 通常是java虚拟机中最大的一块内存区域

  3. 主要作为java对象的主要存储区域

  4. JVMS明确要求该区域需要实现自动内存管理,即常说的GC,但并不限制采用那种算法和技术去实现。

  5. 可能出现OutOfMemoryError异常

  • java虚拟机栈(线程私有)

  1. 线程私有

  2. 后进先出(LIFO)栈

  3. 用于执行JAVA方法。栈帧存储局部变量表、操作数栈、动态链接、方法返回地址和一些额外的附加信息。程序执行时栈帧入栈;执行完成后栈帧出栈,支撑java方法的调用、执行和退出

  4. 肯能会出现OutOfMemoryError异常和StackOverFlowError异常

  • 本地方法栈(线程私有)

  1. 线程私有

  2. 后进先出(LIFO)栈

  3. 作用是支撑Native方法的调用、执行和退出

  4. 可能出现OutOfMemoryError异常和StackOverflowError异常

  5. 有一些虚拟机(如HotSpot)将Java虚拟机栈和本地方法栈合并实现

  • 方法区(线程共有)

(1)方法区

  1. 全局共享

  2. 作用是存储java类的结构信息。用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。但是已经被最新的 JVM 取消了。现在,被加载的类作为元数据加载到底层操作系统的本地内存区。

  3. JVMS不要求该区域实现自动内存管理,但是商用Java虚拟机都能够自动管理该区域的内存

  4. 可能出现OutOfMemoryError异常

(2)运行时常量区

  1. 全局共享

  2. 是方法区的一部分

  3. 作用是存储java类文件常量池中的符号信息

  4. 可能出现OutOfMemoryError异常

2、JVM内存区域划分相关概念

  • 栈帧的概念和特征

  1. Java虚拟机栈中存储的内容,它被用于存储数据和部分过程结果的数据结构,同时也被用来处理动态链接、方法返回值和异常分派

  2. 一个完整的栈帧包含:局部变量表、操作数栈、动态连接信息、方法正常完成信息和方法异常完成信息

  • 局部变量表概念和特征

  1. 由若干个Slot组成,长度由编译期决定

  2. 单个Slot可以存储一个类型为boolean,byte,char,short,float,reference和returnAddress的数据,两个Slot可以存储一个类型为long或double的数据

  3. 局部变量表用于方法间参数传递,以及方法执行过程中存储基础数据类型的值和对象的引用

  • 操作数栈的概念和特征

  1. 是一个后进先出栈,由若干个Entry组成,长度由编译期决定

  2. 单个Entry即可以存储一个Java虚拟机中定义的任意数据类型的值,包括long和double类型,但是存储long和double类型的Entry深度为2,其他类型的深度为1

  3. 在方法执行过程中,栈帧用于存储计算参数和计算结果;在方法调用时,操作数栈也用来准备调用方法的参数以及接收方法返回结果

  • 直接内存

  1. 并非JVMS定义的标准java运行时内存区域

  2. 随jdk1.4中加入的nio被引入,母的是避免在java堆和native堆中来回复制数据带来的性能损耗

  3. 全局共享

  4. 能被自动管理,但是在检测手段上可能会有一些简陋

  5. 可能出现OutOfMemoryError异常

3、内存中的栈(stack)、堆(heap)和静态区(static area)的用法

通常我们定义一个基本数据类型的变量,一个对象的引用,还有就是函数调用的现场保存都使用内存中的栈空间;而通过new关键字和构造器创建的对象放在堆空间;程序中的字面量(literal)如直接书写的100、”hello”和常量都是放在静态区中。栈空间操作起来最快但是栈很小,通常大量的对象都是放在堆空间,理论上整个内存没有被其他进程使用的空间甚至硬盘上的虚拟内存都可以被当成堆空间来使用。

4、java中堆和栈的区别

栈内存 :栈内存首先是一片内存区域,存储的都是局部变量,凡是定义在方法中的都是局部变量(方法外的是全局变量),for循环内部定义的也是局部变量,是先加载函数才能进行局部变量的定义,所以方法先进栈,然后再定义变量,变量有自己的作用域,一旦离开作用域,变量就会被释放。栈内存的更新速度很快,因为局部变量的生命周期都很短。

堆内存 :存储的是数组和对象(其实数组就是对象),凡是new建立的都是在堆中,堆中存放的都是实体(对象),实体用于封装数据,而且是封装多个(实体的多个属性),如果一个数据消失,这个实体也没有消失,还可以用,所以堆是不会随时释放的,但是栈不一样,栈里存放的都是单个变量,变量被释放了,那就没有了。堆里的实体虽然不会被释放,但是会被当成垃圾,Java有垃圾回收机制不定时的收取。

JVM是基于堆栈的虚拟机.JVM为每个新创建的线程都分配一个堆栈.也就是说,对于一个Java程序来说,它的运行就是通过对堆栈的操作来完成的。堆栈以帧为单位保存线程的状态。JVM对堆栈只进行两种操作:以帧为单位的压栈和出栈操作。

堆与栈的区别

1.栈内存存储的是局部变量而堆内存存储的是实体;

2.栈内存的更新速度要快于堆内存,因为局部变量的生命周期很短;

3.栈内存存放的变量生命周期一旦结束就会被释放,而堆内存存放的实体会被垃圾回收机制不定时的回收。

4.堆是先进先出,后进后出。栈是后进先出,先进后出


24人点赞 返回栏目 提问 分享一波

小礼物走一波,支持作者

还没有人赞赏,支持一波吧

留言(问题紧急可添加微信 xxl18963067593) 评论仅代表网友个人 留言列表

暂无留言,快来抢沙发吧!

本刊热文
网友在读
手机扫码查看 手机扫码查看