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, ...
随机推荐
- Set集合转换为List集合
举个栗子,看图:
- 【机器学习】K-means聚类分析
前言 聚类问题是无监督学习的问题,算法思想就是物以类聚,人以群分,聚类算法感知样本间的相似度,进行类别归纳,对新输入进行输出预测,输出变量取有限个离散值.本次我们使用两种方法对鸢尾花数据进行聚类. 无 ...
- # Vue3 setup 函数
Vue3 setup 函数 vue2 和 vue3 开发的区别 首先,目前来说 vue3 发布已经有一段时间了,但是呢,由于还处于优化完善阶段,对于 vue3 开发项目的需求不是很高,主要还是以 vu ...
- 5-12 RabbitMQ 消息队列
RabbitMQ 什么是RabbitMQ RabbitMQ 是一个由 Erlang 语言开发的 AMQP 的开源实现. AMQP :Advanced Message Queue,高级消息队列协议.它是 ...
- IDEA快捷键-03
用了很久的eclipse,换了新的公司,跟着团队的习惯也转到idea上来了.在这里记录下对idea的认识,常用的idea快捷键及使用技巧. 对比eclipse每个workspace打开一个窗口,ide ...
- Hbase学习(三)过滤器 java API
Hbase学习(三)过滤器 HBase 的基本 API,包括增.删.改.查等. 增.删都是相对简单的操作,与传统的 RDBMS 相比,这里的查询操作略显苍白,只能根据特性的行键进行查询(Get)或者根 ...
- 20220722-Java构造器
Java构造器知识总结 来源:B站韩顺平老师Java入门教学 代码示例 class Person { int age; String name; public Person(int pAge, Str ...
- 使用JDK的同步容器时,应该避免那些坑?
摘要:在使用JDK中的同步容器时,应该尽量避免哪些坑 本文分享自华为云社区<[高并发]亿级流量高并发秒杀系统商品"超卖"了,只因使用的JDK同步容器中存在这两个巨大的坑!!( ...
- 关于微信小程序生产环境体验版获取不到openId的问题(大坑)
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_119 我们知道openid是微信用户验证的重要标识,支付功能严重依赖这个东西,之前我们做微信支付的时候是通过在微信客户端直接调用官 ...
- 羽夏看Linux内核——中断与分页相关入门知识
写在前面 此系列是本人一个字一个字码出来的,包括示例和实验截图.如有好的建议,欢迎反馈.码字不易,如果本篇文章有帮助你的,如有闲钱,可以打赏支持我的创作.如想转载,请把我的转载信息附在文章后面,并 ...