JVM运行时的数据区域划分图如下,该图是JVM内存模型最主要的内容。

从图中可以看出来,JVM将内存主要划分为五个部分:程序计数器、Java虚拟机栈、本地方法栈、Java堆和方法区。这些被划分为用途不一的数据区域有着各自的特点,它们都有自己创建和销毁的时间,有的区域随着进程的启动而存在,有的是伴随着用户线程的启动而建立、随着线程的结束而销毁。

(一) 程序计数器(Program Counter Register)

1> 内存空间较小;

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

功能:a、在JVM中,字节码解释器的工作进行就是通过改变计数器的值来选取下一条需要执行的字节码指令

b、在3>中有解释,是作为线程切换回来继续执行的标记点

3> 线程私有;

线程私有:通俗来讲就是每一个线程在执行时都有一个独立的程序计数器,各个线程被独立存储。目的是为了记录所执行的线程进行到了哪一步。这样设计的原因主要是由多线程的实现方式所决定的,在Java虚拟机中,多线程的实现是通过线程轮流切换并分配处理器执行时间的方式,也就是在任何一个具体的时刻下,一个处理器只能够执行一个线程下的代码指令,这样在不断的线程切换过程中,同一个线程想要继续往下执行,就必须知道它上一次执行的位置,这个工作就是通过程序计数器完成的。

4> 计数器的值;

若线程正在执行的是Java方法:正在执行的虚拟机字节码指令的地址;

若线程正在执行的是Native方法:空值(Undefined);

Native方法(本地方法):为了补充Java语言无法直接访问系统底层的一种方法,由C或C++语言完成,实际上Native Method就是Java调用非Java代码的接口。

5> 计数器这块内存区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域。

6> 生命周期与线程相同。

(二)Java虚拟机栈(Java Stack)

1> 定义:描述Java方法执行的内存模型;

a、详细解释:每个方法执行时都会创建一个栈帧,在这个栈帧中存放着“局部变量表、操作数栈、动态链接、方法出口等”。

以我的理解就是这一块内存就是一个栈,栈帧是Java虚拟机栈的诸多元素,每一个栈帧都代表这一个方法正在被执行,其中存放着一些有关该方法中信息。

每一个方法从调用一直到执行结束,也就对应着一个栈帧在Java虚拟机栈中入栈出栈的过程。

b、局部变量表:

基本数据类型、(64位的long和double类型的数据会占用2个局部变量空间,其余占1个)

对象引用、(reference类型??,不同于对象本身,可能是一个指向对象起始地址的引用指针,也可能                                              是指向一个代表对象的句柄或其他与此对象相关的位置)

returnAddress类型 、(指向了一条字节码指令的地址)

局部变量表所需的内存空间在编译期间完成分配,所以在线程进行时调用了一个方法,为之创建的栈帧中局部变量空间是完全确定的,并且在方法执行过程中不会改变局部变量表的大小。

2> 线程私有;

线程私有: 也就是和计数器一样,每一个线程有独立的Java虚拟机栈,这个线程中的每个方法执行过程就会创建一个栈帧,方法执行的全过程就是栈帧在该线程对应的虚拟机栈中入栈和出栈的过程。

3> 生命周期与线程相同;

4> 该内存区域两种异常状况:

a、线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常;

b、若虚拟机支持动态扩展,如果扩展时无法申请到做够的内存,就会抛出OutOfMemoryError异常。

StackOverFlowError表示当前线程申请的栈超过了事先定好的栈的最大深度,但内存空间可能还有很多。

而OutOfMemoryError是指当线程申请栈时发现栈已经满了,而且内存也全都用光了。

5> 不能简单地将Java内存区简单分为堆和栈。

这样区分太过粗糙,只不过是将对象和局部变量区分开,简单地认为对象存放在堆中,局部变量存放在栈中。其实从上面的整理中也可以看出来,Java虚拟机栈实际上是由这些栈帧组成的,而每个栈帧中的内容并不只有局部变量表。

(三)本地方法栈

1> 定义:与Java虚拟机栈的定义很相似,可以说是Native方法执行的内存模型;

2> 虚拟机规范中对本地方法栈中方法使用的语言、使用方式与数据结构并没有强制规定。甚至有的虚拟机(Sun HotSpot)直接就把本地方法栈和虚拟机栈合二为一;

3> 抛出StackOverflowError和OutOfMemoryError异常的情况与Java虚拟机栈是一样的;

4> 其他特性参考Java虚拟机栈。

(四)Java堆

1> 系Java虚拟机所管理内存中最大的一块,虚拟机启动时创建;

2> 被所有线程共享;

所有地线程都可以访问不同地对象,从内存分配地角度来看,线程共享地Java堆中可能划分出多个线程私有地分配缓冲区(TLAB),不过无论如何划分,无论哪个区域,存放地都是对象实例,这样不同地线程将各自地对象实例放在了看似共享的Java堆的各自的缓冲区上,这样的好处是可以更好的回收内存,也可以更快分配内存。

3> 唯一目的就是存放对象实例,几乎所有实例对象都存在此处;

在Java虚拟机规范中描述为:所有的对象实例以及数组都要在这里分配内存。但是随着JIT编译器的发展与逃逸分析技术逐渐成熟,栈上分配、标量替换优化技术将会导致一些微妙的变化发生,所以这里会严谨地加上“几乎所有”而不是全部,至于什么是逃逸分析,栈上分配,标量替换,以后学习中应该会专门去了解学习一下吧。

4>可以处于物理上不连续的内存空间,但逻辑上需要连续;

5> 可以实现固定大小的,也可以是可扩展的。若在堆中没有内存完成实例分配,并且堆也无法再扩展时,将抛出OutOfMemoryError异常;

6> 又称“GC堆'(Garbage Cpllected Heap)

内存回收用到的终极算法:分代收集算法,今后可以专门学习一下,该算法也是多个算法的整合。

(五) 方法区(Method Area)

1> 与Java堆类似,各线程共享的内存区域;

2> 存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等;

3> 规范中描述为堆的一个逻辑部分,习惯称为Non-Heap(非堆),目的是为了与Java堆区分;

4> 被称作“永久代”;

本质上两者并不一样,这样的叫法是因为HotSpot虚拟机的设计团队选择把GC分代收集扩展至方法区,或者说使用永久代来实现方法区而已,这样GC收集器就能像管理Java堆一样管理这部分内存,省去专门为方法区编写内存管理代码的工作。当然方法区也可以不进行GC收集。

5> 不需要连续的内存和可以选择固定大小或者可扩展外,也可以不实现GC收集;

该区域的内存回收目标主要是针对常量池的回收和对类型的卸载,但效果不好,条件苛刻,但是对于这部分的回收确实是有必要的。

6> 当方法区无法满足内存分配需求时,将抛出OutOfMemoryError异常

(六) 运行时常量池

1> 方法区的一部分;

Class文件除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池,用于存放编译时生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池中存放。

2> 受到方法区内存的限制,当常量池无法再申请到内存时会抛出OutOfMemoryError异常;

(七) 直接内存

1> 不属于虚拟机运行时数据区的一部分,也不是规范中的定义;

2> JDK1.4加入了NIO类,一种基于通道与缓冲区的新I/O方式,NIO可以使用Native函数库直接分配堆外内存,然后通过一个存储在Java堆中的DirectByteBuffer对象作为直接内存的引用来操作直接内存,这样可以避免在Java堆和Native堆来回复制数据,从而提高性能;

3> 受总内存影响,也会出现OutOfMemoryError异常。

以上总结的就是JVM内存模型的相关概念和知识点,前五项以及那张内存模型图需要牢记,其中有些许疑问,不过也都是某些概念上的问题,具体关于每一块内存区域的定义作用,抛出的异常类型,已经理解。
————————————————
版权声明:本文为CSDN博主「Adelaide_Guo」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Adelaide_Guo/article/details/75394973

JVM内存模型小结的更多相关文章

  1. JVM内存模型和结构详解(五大模型图解)

    JVM内存模型和Java内存模型都是面试的热点问题,名字看感觉都差不多,实际上他们之间差别还是挺大的. 通俗点说,JVM内存结构是与JVM的内部存储结构相关,而Java内存模型是与多线程编程相关@mi ...

  2. JVM内存模型 小小结

    可以看一下我的另一篇总结 JVM运行时数据区与JVM堆内存模型小结 推荐一篇文章,尚学堂的 Java内存模型深度解读 . 不方便全文转载,就摘录下吧. 以往的认知都是以基本类型.引用类型.常量.方法等 ...

  3. JVM运行时数据区与JVM堆内存模型小结

    前提 JVM运行时数据区和JVM内存模型是两回事,JVM内存模型指的是JVM堆内存模型. 那JVM运行时数据区又是什么? 它包括:程序计数器.虚拟机栈.本地方法栈.方法区.堆. 来看看它们都是干嘛的 ...

  4. Java基础知识强化100:JVM 内存模型

    一. JVM内存模型总体架构图:  方法区和堆由所有线程共享,其他区域都是线程私有的 二. JVM内存模型的结构分析: 1. 类装载器(classLoader) 类装载器,它是在java虚拟机中用途是 ...

  5. JVM内存模型、指令重排、内存屏障概念解析

    在高并发模型中,无是面对物理机SMP系统模型,还是面对像JVM的虚拟机多线程并发内存模型,指令重排(编译器.运行时)和内存屏障都是非常重要的概念,因此,搞清楚这些概念和原理很重要.否则,你很难搞清楚哪 ...

  6. JVM内存模型和性能优化 转

    JVM内存模型和性能优化 JVM内存模型优点 内置基于内存的并发模型:      多线程机制 同步锁Synchronization 大量线程安全型库包支持 基于内存的并发机制,粒度灵活控制,灵活度高于 ...

  7. JVM内存模型和性能优化

    JVM内存模型优点 内置基于内存的并发模型:      多线程机制 同步锁Synchronization 大量线程安全型库包支持 基于内存的并发机制,粒度灵活控制,灵活度高于数据库锁. 多核并行计算模 ...

  8. JVM初探 -JVM内存模型

    JVM初探 -JVM内存模型 标签 : JVM JVM是每个Java开发每天都会接触到的东西, 其相关知识也应该是每个人都要深入了解的. 但接触了很多人发现: 或了解片面或知识体系陈旧. 因此最近抽时 ...

  9. JVM内存模型和关键参数设置

    一. JVM内存模型: Jvm内存模型是学好Java很重要的一部分,该部分学习能让我们在系统运维的时候,或者优化服务器的时候能够有方法,懂原理. 二. Jvm关键参数: 1. 堆大小设置参数: -Xm ...

随机推荐

  1. 2. 堪比JMeter的.Net压测工具 - Crank 进阶篇 - 认识yml

    目录 堪比JMeter的.Net压测工具 - Crank 入门篇 堪比JMeter的.Net压测工具 - Crank 进阶篇 - 认识yml 堪比JMeter的.Net压测工具 - Crank 进阶篇 ...

  2. wireshark-1

    wireshark-1题目来源: 广西首届网络安全选拔赛题目描述:黑客通过wireshark抓到管理员登陆网站的一段流量包(管理员的密码即是答案). flag提交形式为flag{XXXX}附件解压后, ...

  3. while read line [linux] shell 学习

    转至:https://blog.csdn.net/qq_22083251/article/details/80484176 循环中的重定向 或许你应该在其他脚本中见过下面的这种写法: while re ...

  4. 用WebDev.WebServer40.EXE调试VS代码

    1.找到WebDev.WebServer40的录井,一般位于C:/Program Files (x86)/Common Files/Microsoft Shared/DevServer/10.0/We ...

  5. JAVA——运算符

    目录 运算符 1.算术运算符 练习题: 2.关系运算符(比较运算符) 3.逻辑运算符 3.1&& 和 & 使用区别 3.2|| 和 | 使用区别 3.3 取反 基本规则 3.4 ...

  6. 在矩池云上复现 PaddleGAN 照片转油画风格教程

    我选用的是cuda10.1纯镜像 案例来自paddlepaddle官方PaddleGAN库中,可以查看 https://github.com/PaddlePaddle/PaddleGAN/ https ...

  7. LGP2522题解

    双倍经验题. 柯以看成是P3455的扩展. 首先这个范围内是数我们柯以用类似二维前缀和的思想,看成: \(ans(a,b,c,d)=ans(1,b,1,d)+ans(1,a-1,1,c-1)-ans( ...

  8. Excel文件导入SQL Server数据库

    Excel表格的使用可谓是非常广泛,博主也简单百度了一下Excel的发展. 发展历程: 1982年 Microsoft推出了它的第一款电子制表软件-Multiplan,并在CP/M系统上大 Excel ...

  9. C#/Vsto中CustomTaskPanes和Ribbon的使用方法

    在工作中有一个需求,需要添加工作区选项卡,Excel中CustomTaskPanes面板很适合这样的场景,而非集中处理在Excel的Ribbon面板中,毕竟在大型项目中表现层已经过于复杂了.首先写一个 ...

  10. [JS基础] 带你深入了解JS原型

    简介 下面这张图大家应该很很熟悉了,各位大佬讲原型及原型链的时候是大部分都会用到下面这张图片的 我想以自己的方式来讲述一遍,一是帮助我自己更好的复习,二是希望能够帮助到想要复习或者学习原型的同学 在讲 ...