java 虚拟机在执行java程序的过程中会把它所管理的内存划分为若干个不同的数据区域,如图。各个区域有各自的用途,以及创建时间和销毁时间,有的区域随着虚拟机进程启动而存在,有些区域则依赖用户线程的启动和结束而建立和销毁。

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

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

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

  • 方法区:在类装载器加载class文件到内存的过程中,虚拟机会提取其中的类型信息,并将这些信息存储到方法区。方法区用于存储已被虚拟机加载的类信息、常量、静 态变量、即时编译器编译后的代码等数据。由于所有线程都共享方法区,因此它们对方法区数据的访问必须被设计为是线程安全的。。在JVM规范中,没有强制要求方法区必须实现垃圾回收。很多人习惯将方法区称为“永久代”,是因为HotSpot虚拟机以永久代来实现方法区,从而JVM的垃圾收集器可以像管理堆区一样管理这部分区域,从而不需要专门为这部分设计垃圾回收机制。垃圾回收器在回收的时候,也仅仅针对常量池和对类型的回收。不过自从JDK7之后,Hotspot虚拟机便将运行时常量池从永久代移除了。

  • java堆:用于存储java程序创建的对象实例及数组,被所有线程共享,在虚拟机启动时创建,也是垃圾收集器管理的最主要区域,也称GC堆。

  • java栈:线程私有,生命周期与线程相同。Java栈也称作虚拟机栈(Java Vitual Machine Stack),也就是我们常常所说的栈,跟C语言的数据段中的栈类似。事实上,Java栈是Java方法执行的内存模型。为什么这么说呢?下面就来解释一下其中的原因。

    Java栈中存放的是一个个的栈帧,每个栈帧对应一个被调用的方法,在栈帧中包括局部变量表(Local Variables)、操作数栈(Operand Stack)、指向当前方法所属的类的运行时常量池(运行时常量池的概念在方法区部分会谈到)的引用(Reference to runtime constant pool)、方法返回地址(Return Address)和一些额外的附加信息。当线程执行一个方法时,就会随之创建一个对应的栈帧,并将建立的栈帧压栈。当方法执行完毕之后,便会将栈帧出栈。 因此可知,线程当前执行的方法所对应的栈帧必定位于Java栈的顶部。讲到这里,大家就应该会明白为什么 在 使用 递归方法的时候容易导致栈内存溢出的现象了以及为什么栈区的空间不用程序员去管理了(当然在Java中,程序员基本不用关系到内存分配和释放的事情,因为 Java有自己的垃圾回收机制),这部分空间的分配和释放都是由系统自动实施的。对于所有的程序设计语言来说,栈这部分空间对程序员来说是不透明的。下图 表示了一个Java栈的模型:

    局部变量表,是指存放了编译期间可知的各种基本数据类型(boolean、byte、char、short、int、float、long、double)、对象引用(reference类型)和returnAddress类型(指向了一条字节码指令的地址)。其中64位长度的long和double类型的数据会占用2个局部变量的空间,其他的只占用1个。局部变量表所需的空间是在编译时完成分配的,当进入一个方法时,这个方法在帧中分配多大的局部变量空间是完全确定的,因此,在方法运行期间不会改变局部变量表的大小。

    操 作数栈,想必学过数据结构中的栈的朋友想必对表达式求值问题不会陌生,栈最典型的一个应用就是用来对表达式求值。想想一个线程执行方法的过程中,实际上就 是不断执行语句的过程,而归根到底就是进行计算的过程。因此可以这么说,程序中的所有计算过程都是在借助于操作数栈来完成的。

    指向运行时常量池的引用,因为在方法执行的过程中有可能需要用到类中的常量,所以必须要有一个引用指向运行时常量。

    方法返回地址,当一个方法执行完毕之后,要返回之前调用它的地方,因此在栈帧中必须保存一个方法返回地址。

    由于每个线程正在执行的方法可能不同,因此每个线程都会有一个自己的Java栈,互不干扰。

  • 本地方法栈:本地方法栈与Java栈的作用和原理非常相似。区别只不过是Java栈是为执行Java方法服务的,而本地方法栈则是为执行本地方法(Native Method)服务的。在JVM规范中,并没有对本地方发展的具体实现方法以及数据结构作强制规定,虚拟机可以自由实现它。在HotSopt虚拟机中直接就把本地方法栈和Java栈合二为一。

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

JVM内存区域划分及其管理机制相关推荐

  1. mfc强制局部区域刷新_简述JVM内存区域划分

    我们在Java编程时少不了程序优化,而程序优化的前提是知道JVM的内存是如何划分的,那么我们今天来大体了解下. 在看JVM内存区域划分之前,先来看一下Java程序具体执行的过程: 如上图所示,首先Ja ...

  2. 3、JVM内存区域划分

    内存区域划分图: 方法区: 存储类信息.常量.静态变量.JIT即时编译器编译后的代码.所有线程共享. 当JVM中的类加载器将一个类的.class文件加载到JVM内存时,是把这个.class信息加载到了 ...

  3. JVM内存区域划分 EDEN SPACE、SURVIVOR SPACE、TENURED GEN

    JVM区域总体分两类,heap区和非heap区.heap区又分:Eden Space(伊甸园).Survivor Space(幸存者区).Tenured Gen(老年代-养老区). 非heap区又分: ...

  4. JVM内存区域划分总结

    发现网上有两个版本的JVM内存划分,一个是按照<深入理解JVM虚拟机>上的版本,包含程序计数器等,按照是否线程共享划分. 另一个我觉得更好记一些,也更适合我自己,在这里记录一下. 首先上思 ...

  5. 3.JVM内存区域划分

    前言 上一节我们详细学习了类加载器,我们接着思考下一个问题: 类加载器将class文件加载到JVM内存的什么位置? JVM内部内存是怎样划分的? 通过本节我们将寻找到答案,并将掌握以下知识: 1. J ...

  6. JVM内存区域划分Eden Space、Survivor Space、Tenured Gen,Perm Gen解释

    jvm区域总体分两类,heap区和非heap区.heap区又分:Eden Space(伊甸园).Survivor Space(幸存者区).Tenured Gen(老年代-养老区). 非heap区又分: ...

  7. 2022-04-07 西安 javaSE(04) 方法可变参数、重载、递归,数组、冒泡排序、二分查找、动态操作,二维数组、jvm内存区域划分

    方法 1.方法传递参数 形参是基本类型: 1.参数传递的内容是该基本类型的数据值.   2.对形式参数的改变不会影响实际参数的数据值 形参是引用类型:     1.参数传递的是地址值     2.对形 ...

  8. JVM内存区域划分Eden Space\Survivor Space\Tenured Gen\Perm Gen

    JVM区域分heap区和非heap区. 1)heap区:Eden Space(伊甸园),Survivor Space(幸存者区),Tenured Gen(老年代-养老区). 2)非heap区:Code ...

  9. JVM的内存区域划分(转)

    原文链接:JVM的内存区域划分 JVM的内存区域划分 学过C语言的朋友都知道C编译器在划分内存区域的时候经常将管理的区域划分为数据段和代码段,数据段包括堆.栈以及静态数据区.那么在Java语言当中,内 ...

最新文章

  1. 基于道路标线的城市环境单目定位
  2. 网络DevOps探索与实践
  3. 发布一个用于WinCE的矢量图控件
  4. OpenGL超级宝典笔记——遮挡查询 [转]
  5. 微信小程序python token验证_微信小程序python 用户认证
  6. Solr router 路由介绍
  7. 5 点击图换下一张_如何制作一张高点击率主图
  8. java中的过滤器:Filter
  9. vue 多点触控手势_手写 Vue 手势组件__Vue.js
  10. 使用JMeter如何实现上传文件
  11. plsql为字段添加自增主键
  12. 国家多部委发布13份“十四五”规划,115项重大工程​
  13. ACM基础题——小刘认亲
  14. 408计算机组成原理学习笔记——存储系统
  15. Android开发丶openinstall的集成和使用(推广二维码)
  16. conda的一个坑。channels: - https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/pytorch - https://mirro
  17. flutterdio_强大的Flutter http请求库dio
  18. 毫秒级返回数据,TDengine 在大疆车载智能驾驶云端平台上的应用
  19. yoyo跑_yoyo是什么意思
  20. oogle advertiser api开发概述——速率限制

热门文章

  1. Httpclient 实现带参文件上传
  2. 命令行下django-admin.py参数不起作用的问题解决
  3. 【荐】中国最有潜力的十位企业家(IT行业占大半)
  4. 显式接口成员实现你知道吗??
  5. 从理论角度理解L1、L2正则化
  6. eth0,eth1,eth2,lo是什么
  7. linux下 C编程改变输出字体颜色
  8. 迫零响应法用于MIMO系统
  9. linux 单网卡 路由,CentOS下双网卡单网关路由配置
  10. [云炬创业基础笔记]第二章创业者测试18