前言

说到Java内存区域,可能很多人第一反应是"堆栈"。首先堆栈不是一个概念,而是两个概念,堆和栈是两块不同的内存区域,简单理解的话,堆是用来存放对象而栈是用来执行程序的。对于Java程序员来说,在虚拟机自动内存管理机制的帮助下,不再需要为每一个new操作去配对delete/free代码, 不容易出现内存泄露内存溢出问题。但是,也正是因为Java把内存控制权交给了虚拟机,一旦出现内存泄露和内存溢出的问题,就难以排查,因此一个好的 Java程序员应该去了解虚拟机的内存区域以及会引起内存泄露和内存溢出的场景。

运行时数据区域

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

1、线程独有的内存区域

(1)PROGRAM COUNTER REGISTER,程序计数器

这块内存区域很小,它是当前线程所执行的字节码的行号指示器,字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令。分支,循环,异常处理等基础功能都需要依赖这个计数器来完成!如果线程正在执行的是一个Java方法时这个计数器记录的是正在执行的虚拟机字节码指令的地址,如果执行的是一个Native方法,那这个计数器是空的。

由于Java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现,为了线程切换之后能恢复到正确执行的位置,每个线程都需要一个独立的程序计数器,各个线程之间的程序计数器互不影响,独立存储。我们称这类内存区域是线程的私有内存!

程序计数器是唯一一个在java虚拟机规范中没有规定任何OOM情况的区域!

(2)JAVA VIRTUAL MACHINE STACK,虚拟机栈

生命周期和线程相同。虚拟机栈描述的是java方法执行的内存模型。每个方法执行的同时都会创建一个栈帧,用于存储局部变量表、操作数栈、动态链接、方法出口等信息,每一个方法从调用直至执行完毕的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。栈的大小和具体JVM的实现有关,通常在256K~756K之间。

在java虚拟机规范中,对这个区域规定了两种异常状况,如果线程请求的栈深度大于虚拟机所允许的深度,将会抛出StackOverflowError异常。如果虚拟机栈可以动态扩展,如果扩展时无法申请到足够的内存,就会抛出OOM异常!

(3)NATIVE METHOD STACK,方法栈

和虚拟机栈起的作用一样,只不过虚拟机栈为虚拟机执行Java方法服务,而本地方法栈则为虚拟机使用到的Native方法服务。虚拟机规范并没有对这个区域有什么强制规定,因此我们使用的HotSpot虚拟机,就干脆没有这块区域了,它和虚拟机栈是一起的。异常情况同虚拟机栈

2、线程间共享的内存区域

(1)HEAP,堆

大多数应用,堆都是Java虚拟机所管理的内存中最大的一块,它在虚拟机启动时创建,被所有线程共享!此内存唯一的目的就是存放对象实例。Java堆是垃圾收集器管理的主要区域,由于现在垃圾收集器采用的基本都是分代收集算法,所以堆还可以细分为新生代和老年代,再细致一点还有Eden区、From Survivior区、To Survivor区,细分堆只是为了更好地回收内存,或者更快地分配内存;

如果堆中没有内存完成实例的分配并且堆也无法再扩展时将会抛出OOM!

(2)METHOD AREA,方法区

这块区域是各个线程共享的区域,用于存储已经被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据,虚拟机规范是把这块区域描述为堆的一个逻辑部分的,但实际它应该是要和堆区分开的。从上面提到的分代收集算法的角度看,HotSpot中,方法区≈ 永久代。不过JDK 7之后,我们使用的HotSpot应该就没有永久代这个概念了,会采用Native Memory来实现方法区的规划了。

(3)RUNTIME CONSTANT POOL,运行时常量池

上面的图中没有画出来,因为它是方法区的一部分。Class文件中除了有类的版本信息、字段、方法、接口等描述信息外,还有一项信息就是常量池,用于存放编译期间生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池中,另外翻译出来的直接引用也会存储在这个区域中。这个区域另外一个特点就是动态性,Java并不要求常量就一定要在编译期间才能产生,运行期间也可以在这个区域放入新的内容,String.intern()方法就是这个特性的应用。

3、直接内存

直接内存并不是虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域。 但是这部分内存也被频繁地使用,而且也可能导致内存溢出问题。JDK1.4中新增加了NIO,引入了一种基于通道与缓冲区的I/O方式,它可以使用 Native函数库直接分配堆外内存,然后通过一个存储在Java堆中的DirectByteBuffer对象作为这块内存的引用进行操作。这样能在一些 场景中显著提高性能,因为避免了在Java堆和Native堆中来回复制数据。显然,本机直接内存的分配不会受到Java堆大小的限制,但是,既然是内 存,肯定还是会受到本机总内存(包括RAM、SWAP区)大小以及处理器寻址空间的限制。

@JVM内存模型(运行时数据区)相关推荐

  1. JVM内存模型——运行时数据区的特点和作用

    文章目录 前言 1程序计数器 2本地方法栈 3虚拟机栈 3.1局部变量表 3.2操作数栈 3.3动态连接 3.4返回地址 4方法区 5堆 5.1查看方法区跟堆大小 5.2新生代跟老年代 5.3什么时候 ...

  2. Java JVM内存模型(运行时数据区域)详解

    详细介绍了JVM运行时数据区域,包括方法区.堆空间.栈空间.本地方法栈.程序计数器.常量池.直接内存.字面量.符号引用.直接引用. Java程序在运行时,需要在内存中的分配空间.为了提高运算效率,ja ...

  3. [JVM]了断局: “运行时数据区“理论梳理

    Table of Contents 一.前言 二.运行时数据区 2.1.程序计数器 2.2.Java堆 2.3.方法区 2.4.运行时常量池 2.5.直接内存 2.6.Java虚拟机栈 2.7.本地方 ...

  4. JVM系列之运行时数据区

    1.运行时数据区 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域,这些区域有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而一直存在,有些区域则是 ...

  5. 深入理解JVM底层原理——运行时数据区

    运行时数据区概述和线程 1.运行时数据区概述 !     内存是非常重要的系统资源,是硬盘和CPU的中间仓库及桥梁,承载着操作系统和应用程序的实时运行.JVM内存布局规定了Java在运行过程中内存申请 ...

  6. [二]Java虚拟机 jvm内存结构 运行时数据内存 class文件与jvm内存结构的映射 jvm数据类型 虚拟机栈 方法区 堆 含义...

    前言简介 class文件是源代码经过编译后的一种平台中立的格式 里面包含了虚拟机运行所需要的所有信息,相当于 JVM的机器语言 JVM全称是Java Virtual Machine  ,既然是虚拟机, ...

  7. JVM笔记-13运行时数据区-堆(OOM、年轻代老年代)

    学习JVM的一点简单笔记,宋红康老师jvm讲的很好,感谢. 尚硅谷JVM全套教程,百万播放,全网巅峰(宋红康详解java虚拟机) OOM 异常是什么? 堆空间溢出,存放数据大于堆空间大小. packa ...

  8. 【JVM】3. 运行时数据区及程序计数器

    文章目录 3.1.

  9. 最全的 JVM 面试知识点(一):运行时数据区

    转自: https://blog.csdn.net/keets1992/article/details/92089754 不是码农,不会敲代码的她,却最懂程序员!| 人物志: https://blog ...

最新文章

  1. python3 文件内容搜索 文件名搜索 目录遍历
  2. 基于FPGA的超声波数据图像显示
  3. [工具]-C语言实现:生成一个全是0x0的二进制文件
  4. GO恶意样本实例分析
  5. 使用.NET读取XML文件
  6. linux-简单进程查询
  7. CSS基本选择器之类选择器多类名(CSS、HTML)
  8. Unity实现3D物体叠加到摄像头画面上
  9. 三维计算机视觉(六)--3DSC(3D形状上下文特征)
  10. 14、 Integer 与 int 的区别
  11. 循环buffer的实现_Go语言源码阅读之bytes.Buffer
  12. 小米随身wifi没有网络显示无服务器,小米wifi怎么用 小米随身wifi无法上网怎么办...
  13. windows注册表解析说明
  14. 微信3D小游戏已达数百款,这里肯定有你没玩过的小游戏!
  15. 美团外卖离线数仓建设实践
  16. ios开发 多人语音聊天_iOS语音提醒开发总结
  17. hadoop中HDFS的NameNode原理
  18. 什么是闰年?闰年为什么是366天?为什么不能是100的倍数?
  19. Foo = Foo||Bar ,这行代码是什么意思?为什么要这样写?
  20. 北京大学C语言学习第三天

热门文章

  1. 以服务器时间为基准显示到某一时间的倒计时
  2. 静态成员内部类和非静态成员内部类的实例化方式
  3. Spring MVC Formatter(数据格式化)详解
  4. 专用efi文件包_850个水利水电工程全套表格,施工方/监理方专用表,只发布两天...
  5. .ne中的控制器循环出来的数据如何显示在视图上_让不懂编程的人爱上iPhone开发系列2 iOS12+Swift4.2版-Checklists-16...
  6. spring mysql中文乱码问题_解决Spring下MySQL出现乱码的问题
  7. JavaScript中循环遍历JSON响应
  8. 为什么程序员互相之间不能透露薪水?是怕“凡尔赛”吗?
  9. 我如何开始学习Web开发
  10. android判断是否登陆过_如何判断车辆是否受到过碰撞?_搜狐汽车