JVM的内存区域

2023-11-11

JVM的内存区域

不知不觉都大三了,回头看看以前的Android开发过程,遇到的很多问题都需要深入到源码去解决,这也促使我不断地深入学习Java的相关知识,首先要学习的肯定是JVM。不过JVM的知识体系十分庞杂,JVM的内存区域的划分是学习JVM的基础,所以就从这里开始总结。

运行时数据区域

JVM在执行Java的程序的时候会将内存划分为几个不同的区域:方法区、虚拟机栈、本地方法栈、堆和程序计数器,理解这几个区域后对于Java使用会有很大的帮助,在一定程度上可以减少程序崩溃的概率。
先来一张结构图:
运行时数据区域

1. 方法区

方法区
方法区是各个线程共享的内存区域,它用于储存已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据,在Java虚拟机规范里,这部分被描述成了堆区的一个逻辑部分,但又有“no-heap”的说法,因此不能把它看成堆。
对于主流的HotSpot虚拟机而言,在JDk1.8以前,方法区还有“永久代”的说法,但并不意味着这个区域内不会被GC管理到,相反,HotSpot只是使用“永久代”来实现方法区,这样GC就可以像管理堆内存一样,管理这部分内存,也就不必单独为这块区域编写内存管理代码。但在JDK1.8中,已经不再使用永久代来实现方法区了,取而代之的是“Metaspace”,也叫元空间。元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。因此,默认情况下,元空间的大小仅受本地内存限制,当然也可以通过指令手动指定元空间的大小。
在方法区之中,还有一个运行时常量池,里面储存着编译时期生成的各种字面量和符号引用,这部分的内容将在类加载后进入其中。
对于运行时常量池,虚拟机没有做任何细节要求,不同的提供商实现的虚拟机可以按照自己的需求去实现这个内存区域。
值得注意的是,运行时常量池具备动态性,Java语言并不要求常量一定要只有编译期才能产生,在运行期间也可能有新的常量进入常量池中,String类的intern()方法便利用了这一特性。

1. 虚拟机栈

虚拟机栈
虚拟机栈是线程私有的,它的生命周期与线程相同,它描述的是java方法执行的内存模型:每个方法在执行的时候都会创建一个栈帧,用来储存局部变量表、操作数栈、动态链接和方法出口等信息。
一个方法从调用用直到执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。
在栈帧中还有一个局部变量表,用于存储编译时期可知的各种基本数据类型和对象引用(reference类型,可能是一个指向对象起始地址的指针,也可能是一个指向代表对象的句柄)。局部变量表的内存空间在编译的时候就已经确定了,在方法运行期间不会改变局部变量表的大小。
其实,我们偶尔遇到的StackOverflowError异常就是是因为调用方法的深度过深,又遇到虚拟机栈在动态扩展时无法申请到足够多的内存。

3. 本地方法栈

本地方法栈与虚拟机栈所发挥的作用是非常相似的,他们之间的区别不过是虚拟机栈用于执行java方法,而本地方法栈则用来执行Native方法。
在某些虚拟机中,更是把虚拟机栈和本地方法栈合在了一起使用。

4. 堆

堆
我在最初接触面向对象的概念的时候就被灌输了“栈中存放对象的引用,堆中存放对象的实例”的思想,现在看来对于多数应用来说,堆是JVM所管理的内存最大的区域,也是GC回收垃圾的主要战场,这是被所有线程共享的区域。它的唯一作用就是存放对象的实例,几乎所有对象都会在这里分配内存。
按照JVM分代回收垃圾的思想,堆中可以被分为新生代和老年代,再细致一点的话,堆还可以分为Eden空间、From Survivor空间、To Survivour空间等。并且,从内存分配的角度看,线程共享的堆中可能划分出多个线程私有的分配缓冲区(TLAB)。之所以有这么多的划分方式,都是为了能更好地回收、分配内存。
此外,堆中的物理内存可以不用是连续的,只要逻辑上连续即可,如果在堆中没有内存空间完成对象实例的内存分配,并且又无法扩展时,将会抛出OOM(OutOfMemoryError)异常。

5. 程序计数器

程序计数器
程序计数器是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器。字节码的解释器工作时就是通过改变这个计数器来实现指令的执行,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。
并且,每个线程都有一个独立的程序计数器,各条线程之间的程序计数器不会互相影响,独立储存,负责读取各自线程需要执行的字节码指令,这是一块线程私有的区域。
如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果执行的是Native方法,这个计数器则为空。
值得注意的是,这是唯一一个没有规定任何OutOfMemoryError的情况的区域。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JVM的内存区域 的相关文章

随机推荐

  • MAC上Chrome关闭黑暗模式

    方法 1 打开 Chrome 或基于 Chromium 的浏览器 2 在URL处输入 chrome flags enable force dark 确保 Force Dark Mode for Web Contents 和 Web Plat
  • pandas的引入及Series的基础操作、读取外部文件

    作用 相对于numpy pandas更进一步能帮助处理数值型数据之外的其他类型数据 比如时间序列 字符串等 常用数据类型 Series 一维 带标签数组 DataFrame 二维 Series容器 Series 创建Series数组 语法结
  • 【实用工具】利用MyBatisX插件自动生成代码

    文章目录 1 概述 2 基本使用 2 1 插件安装 2 2 集成数据库 1 概述 MybatisX 是一款基于 IDEA 的快速开发插件 为效率而生 在开发过程中 相信大家都遇到过一个数据库内有着十几张或比之更多的数据表的情况 而面对这众多
  • PHP基础

    php语法初步 php是一种运行在服务器端的脚本语言 可以嵌入到html中 php代码标记 在PHP历史发展中 可以用多种标记来区分php脚本 asp标记 短标记 以上两种基本弃用 如果要使用那么需要在配置文件中开启 脚本标记
  • Jenkins 简介

    Jenkins 简介 为什么要使用 Jenkins 是 Jenkins 还是 Hudson 从 Hudson 到 Jenkins 一个简短的故事 应该使用 Jenkins 还是 Hudson Jenkins 简介 Jenkins 最开始被称
  • failed to accept an incoming connection: connection from 127.0.0.1

    一 报错详细信息 root host 47 98 97 124 tail f tmp zabbix agentd log 11822 20180707 094214 749 Starting Zabbix Agent host 47 98
  • [javascript] Box2D JS初探(一个控制小球的游戏例子)。学习用!

    Box2D 开源物理引擎 第一次接触 主要用途应该是做游戏 不过也可以作些简单的页面特性 比如切割粉碎 拖动带弹性系数 从写了个控制小球运动 可以方向键控制左右和弹跳 碰到障碍物就死掉的DEMO来试试 演示地址 null 这里注意的是 市面
  • 在树莓派和Ubuntu等Linux发行版平台上使用OpenCV原生API调用摄像头等设备时虚拟机崩溃的问题及解决方案

    在树莓派和Ubuntu等Linux发行版平台上使用OpenCV原生API调用摄像头等设备时虚拟机崩溃的问题及解决方案 摘要 本文讨论了在树莓派和Ubuntu等Linux发行版平台上使用OpenCV原生API调用摄像头等设备时可能导致虚拟机崩
  • Quartus II 13.1的安装及使用

    文章目录 一 下载安装注册 二 设计D触发器 2 1 新建工程 2 2 创建原理图和VWF文件 2 3 时序波形仿真 三 调用D触发器 3 1 新建工程 3 2 创建原理图和VWF文件 3 3 波形仿真 四 用Verilog语言写D触发器
  • vue预览tiff格式文件

    vue 预览tiff格式的文件 1 下载tiff js tiff js官网 npm 安装 npm i tiff js S yarn 安装 yarn add tiff js S 安装完成之后通过 img 标签使用即可 div fileInfo
  • 数据结构:手撕图解二叉树(含大量递归图解)

    文章目录 写在前面 二叉树的创建 二叉树的遍历 前序遍历 中序遍历 后序遍历 层序遍历 二叉树的销毁 二叉树节点个数 二叉树叶子节点的个数 二叉树查找值为x的节点 二叉树是否为完全二叉树 写在前面 二叉树的几乎所有实现都是依靠递归实现 递归
  • 51单片机:独立按键控制数码管计数

    按键动作的前沿和后沿会都有大约10ms的抖动 人在按下按键到松开至少需要50ms以上 待考证 此代码实现的功能为给按键计数 并给按键消抖 欢迎邮箱交流 bglei foxmail com 作者 CHNfisher include
  • JS压缩图片

    作者 wuwhs https segmentfault com a 1190000023486410 说明 js image compressor 是一个实现轻量级图片压缩的 javascript 库 压缩后仅有 5kb 在前端页面即可实现
  • 【数据挖掘】特征化分析(信息增益)

    目录 前言 数据预处理 导入库 读取样本数据 计算过程 计算每个属性的熵 计算给定的样本分类所需要的期望信息 计算所有属性的信息增益 结果可视化 信息增益较大的属性下的结果 信息增益较小的属性下的结果 写在后面 前言 这是一个数据挖掘选修课
  • ubuntu系统中新建文件的默认权限

    在ubuntu系统中 当我们使用touch 和 mkdir 新建文件和目录时 并没有指明要赋予它们的权限 在man的帮助手册中也没有找到相应选项 虽然后续我们可以使用chmod 修改文件的权限 但是清楚新建文件的默认权限的来源是十分有必要的
  • 根据采购订单IDN进行MIGO过账的BAPI逻辑

    客户需求 根据ALV上的采购订单IDN进行过账 如果有IDN 就根据IDN过账 如果没有 就根据采购订单过账 BAPI ITEM数据填充如下 DATA ls goodsmvt item TYPE bapi2017 gm item creat
  • 黑马程序员——多线程笔记

    a target blank href http www itheima com android培训 a a target blank href http www itheima com java培训 a 期待与您交流 多线程 一 概念 进
  • python数据分析-Pandas数据清洗

    数据的格式请参考前面Pandas常见操作中数据的格式 数据清洗 1 重复值的处理 重复值一般采取删除法来处理 但有些重复值不能删除 例如订单明细数据或交易明细数据等 data data duplicated 判断重复数据并取出 data d
  • 区块链技术体系,快捷学习路径?

    这两年 数字货币和区块链很火 年初写过一些区块链与比特币的文章 反响也很不错 不少网友催我继续写区块链 我在这个方向未曾深耕 也不敢造次 结合自己的经验 写写区块链涉及的技术体系 以及学习区块链的途径和方法 一 区块链技术体系 数据层 数据
  • JVM的内存区域

    JVM的内存区域 不知不觉都大三了 回头看看以前的Android开发过程 遇到的很多问题都需要深入到源码去解决 这也促使我不断地深入学习Java的相关知识 首先要学习的肯定是JVM 不过JVM的知识体系十分庞杂 JVM的内存区域的划分是学习