1 Java内存区域管理
1 关于自动内存管理
- Java是由jvm来管理内存,包括自动分配以及自动回收,因此它不容易出现内存泄漏和内存溢出问题。
- C/C++,由程序员手动管理内存,手动完成:使用前申请内存,使用后释放内存。
2 运行时数据区域
Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这些区域有各自的用途,以及创建和销毁的时间。
Java虚拟机所管理的内存 包括以下几个运行时数据区域:

2.1 程序计数器
- 程序计数器(Program Counter Register):存储当前线程所执行的字节码指令的内存地址。字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令。【通过PC来寻找下一条要执行的指令】。
- 程序计数器是线程私有的。cpu通过轮流分配时间片来执行线程,为了线程切换后能恢复到正确的执行位置,显然每个线程都需要有一个独立的程序计数器。
- 如果线程正在执行的是一个Java方法,PC记录的是正在执行的字节码指令的地址;如果正在执行的是本地(Native)方法,这个计数器值则应为空。【todo 为什么本地方法时为空】
2.2 虚拟机栈
- 虚拟机栈描述的是Java方法执行的线程内存模型:每个方法被执行的时候,jvm会同步创建一个栈帧[后续章节详解](Stack Frame)用于存储局部变量表、操作数栈、动态连接、方法出口等信息。
- 虚拟机栈也是线程私有的,它的生命周期与线程相同。
2.2.1 局部变量表
JDK8之前,对jvm内存的认知只停留在:堆内存(Heap)和栈内存(Stack),而“栈”通常就是指这里讲的虚拟机栈,或者更多的情况下只是指虚拟机栈中局部变量表部分。
- 局部变量表存储:基本数据类型(八种:boolean、byte、char、short、int、 float、long、double)、对象引用(可能是一个指向对象起始 地址的引用指针)和returnAddress 类型(指向了一条字节码指令的地址)。
- 局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在栈帧中分配多大的局部变量空间是完全确定 的,在方法运行期间不会改变局部变量表的大小。【这里的大小仅值变量槽的数量】
- 局部变量表以局部变量槽(Slot)来存储数据,其中64位长度的long和 double类型的数据会占用两个变量槽,其余的数据类型只占用一个。(通常一个槽占据N个字节,N大小由不同的虚拟机实现决定)。
关于栈的内存数据分析,在后续章节中会有更深入分析,在本节中这里仅引入概念。
2.2.2 操作数栈
关于方法调用时的进栈跟出栈的原理,在《深入理解计算机系统》系列笔记的后续章节中会进行总结。
2.3 本地方法栈
- 本地方法栈(Native Method Stacks)与虚拟机栈作用是非常相似的,其区别只是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的本地(Native) 方法服务。
- 线程私有的。
2.4 堆
- Java堆(Java Heap)存储对象的实例。
- Java堆是线程共享的,且比较大的一块内存区域,在虚拟机启动时创建。
- Java堆既可以被实现成固定大小的,也可以是可扩展的,不过当前主流的Java虚拟机都是按照可扩展来实现的(通过参数-Xmx和-Xms设定)。
- 可弹性伸缩,但不会超过设定的最大容量,如果在Java堆中没有内存完成实例分配,并且堆也无法再 扩展时,Java虚拟机将会抛出OutOfMemoryError异常
- Java堆可以处于物理上不连续的内存空间中,但在逻辑上它应该 被视为连续的。
2.5 方法区
- 方法区存储已被虚拟机加载的class的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据。
- 方法区是线程共享。
- 方法区不需要连续的内存、可以选择固定大小或者可扩展,甚至还可以选择不实现垃圾收集(因为这部分内存通常不满足回收条件)
- 方法区无法满足新的内存分配需求时,将抛出 OutOfMemoryError异常。
2.5.1 运行时常量池
- 存放编译期生成的各种字面量与符号引用
- 运行时常量池(Runtime Constant Pool)是方法区的一部分
3 直接内存
- 首先,直接内存(Direct Memory)并不是虚拟机运行时数据区的一部分,也不是《Java虚拟机规范》中 定义的内存区域
- 它可能导致OutOfMemoryError异常出现,有必要了解。
在JDK 1.4中新加入了NIO(New Input/Output)类,引入了一种基于通道(Channel)与缓冲区 (Buffer)的I/O方式,它可以使用Native函数库直接分配堆外内存,然后通过一个存储在Java堆里面的 DirectByteBuffer对象作为这块内存的引用进行操作。这样能在一些场景中显著提高性能,因为避免了 在Java堆和Native堆中来回复制数据。
显然,本机直接内存的分配不会受到Java堆大小的限制,但是,既然是内存,则肯定还是会受到 本机总内存(包括物理内存、SWAP分区或者分页文件)大小以及处理器寻址空间的限制,一般服务 器管理员配置虚拟机参数时,会根据实际内存去设置-Xmx等参数信息,但经常忽略掉直接内存,使得 各个内存区域总和大于物理内存限制(包括物理的和操作系统级的限制),从而导致动态扩展时出现 OutOfMemoryError异常。
关于内存的深入了解,在《深入理解计算机系统》系列笔记的后续章节中会进行总结。
4 总结
Java内存区域及其数据类别概览:

1 Java内存区域管理的更多相关文章
- 【转】Java内存管理:深入Java内存区域
转自:http://www.cnblogs.com/gw811/archive/2012/10/18/2730117.html 本文引用自:深入理解Java虚拟机的第2章内容 Java与C++之间有一 ...
- Java内存管理:深入Java内存区域
Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来. 概述: 对于从事C和C++程序开发的开发人员来说,在内存管理领域,他们既是拥有最高权力的皇帝 ...
- java虚拟机学习-JVM内存管理:深入Java内存区域与OOM(3)
概述 Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来. 对于从事C.C++程序开发的开发人员来说,在内存管理领域,他们即是拥有最高权力的皇帝又 ...
- Java内存管理:Java内存区域 JVM运行时数据区
转自:https://blog.csdn.net/tjiyu/article/details/53915869 下面我们详细了解Java内存区域:先说明JVM规范定义的JVM运行时分配的数据区有哪些, ...
- JVM自动内存管理机制——Java内存区域(下)
一.虚拟机参数配置 在上一篇<Java自动内存管理机制——Java内存区域(上)>中介绍了有关的基础知识,这一篇主要是通过一些示例来了解有关虚拟机参数的配置. 1.Java堆参数设置 a) ...
- Java内存管理(一):深入Java内存区域
本文转自:http://www.cnblogs.com/gw811/archive/2012/10/18/2730117.html#undefined 推荐查看原文,原文格式更好一些. 本文引用自:深 ...
- 2.1 自动内存管理机制--Java内存区域与内存溢出异常
自动内存管理机制 第二章.Java内存区域与内存溢出异常 [虚拟机中内存如何划分,以及哪部分区域.什么样代码和操作会导致内存溢出.各区域内存溢出的原因] 一.运行时数据区域 Java虚拟机所管理的内存 ...
- 深入理解java虚拟机读书笔记--java内存区域和管理
第二章:Java内存区域和内存溢出异常 2.2运行时数据区域 运行时数据区分为方法区,堆,虚拟机栈,本地方法栈,程序计数器 方法区和堆是线程共享的区域 虚拟机栈,本地方法栈,程序计数器是数据隔离的数据 ...
- Java 内存区域和GC机制分析
目录 Java垃圾回收概况 Java内存区域 Java对象的访问方式 Java内存分配机制 Java GC机制 垃圾收集器 Java垃圾回收概况 Java GC(Garbage Collection, ...
随机推荐
- 利用laravel-echo主动向服务端发送消息,实现在线状态管理
之前在网上翻了半天,也没有找到关于如何 通过laravel-echo主动发送消息 和 在laravel-websockets中自定义控制器 的文章或教程.无奈之下只能翻laravel-echo和lar ...
- ppt/word公式LaTeX环境配置
PPT使用Latex说明 一.下载IguanaTex_v1_57 http://www.jonathanleroux.org/software/iguanatex/download.html Inst ...
- Druid 查询超时配置的探究 → DataSource 和 JdbcTemplate 的 queryTimeout 到底谁生效?
开心一刻 昨晚跟我妈语音 妈:我年纪有点大了,想抱孩子了 我:妈,我都多大了,你还想抱我? 妈:我想抱小孩,谁乐意抱你呀! 我:刚好小区有人想找月嫂,要不我帮你联系下? 妈:你给我滚 然后她直接把语音 ...
- 关于2022年3月9日之后Typora登录不了--已解决
p.s.今天是2022.7.27,软件版本:13.6.1 (以下所有方法,亲自尝试后整理出的) 报错信息: This beta version of typora is expired, please ...
- NOIP提高组模拟赛26
A. LCIS 蓝书原题,CF10D 弱化版 首先直接把 LIS 和 LCS 合起来设计一个 DP . 设 \(dp_{i,j}\) 表示 \(A_{1\dots i}\) 和 \(B_{1\dots ...
- docker + Umami + Postgresql 网站访问分析
1 # docker + Umami + Postgresql 2 # 官方安装文档:https://umami.is/docs/install 3 # 一.创建数据库 4 # 1.创建用户 5 CR ...
- python的嵌入式开发
今天晚上注定我要玩一夜这个东西,太爽了,给力! 烧写固件成功, http://blog.csdn.net/Lingdongtianxia/article/details/78248888 要点总结:如 ...
- 先导,对IOC容器的理解
先导,对IOC容器的理解 通俗的讲就是把你的class类交给spring的IOC容器去管理 需要对该类的属性注入一些值,就可以通过spring提供的xml文件或者注解进行注入 自己使用时在IOC容器工 ...
- 论文解读(DropEdge)《DropEdge: Towards Deep Graph Convolutional Networks on Node Classification》
论文信息 论文标题:DropEdge: Towards Deep Graph Convolutional Networks on Node Classification论文作者:Yu Rong, We ...
- Apache DolphinScheduler 使用文档(5/8):使用与测试
本文章经授权转载,原文链接: https://blog.csdn.net/MiaoSO/article/details/104770720 目录 5. 使用与测试 5.1 安全中心(Security) ...