【深入理解Java虚拟机】自动内存管理机制——内存区域划分
Java与C++之间有一堵有内存动态分配和垃圾收集技术所围成的“高墙”,墙外面的人想进去,墙里面的人却想出来。C/C++程序员既拥有每一个对象的所有权,同时也担负着每一个对象生命从开始到终结的维护责任,而Java最大的优势之一就是将内存控制的权力交给了Java虚拟机。在虚拟机自动内存管理机制的帮助下,程序员几乎不用担心内存泄漏和内存溢出的问题。
然而,这里说的仅仅是几乎不会出现,特殊情况下,一旦出现了类似问题,程序员也需要对虚拟机的自动内存管理机制有所了解,才可能排查出相应的错误。
Java虚拟机内存区域划分
Java虚拟机在执行java程序的过程中,会把它所管理的内存划分为几个不同的数据区域,每个数据区域有各自的用途,有些随虚拟机进程启动而存在,有些随用户线程而存在。这些区域主要包括:程序计数器、Java虚拟机栈、本地方法栈、Java堆、方法区、直接内存。

1. 程序计数器
程序计数器是很小的一个空间,可以看做是当前线程所执行的字节码的行号指示器,也就是用以决定下一条将要执行的字节码指令,比如分支、循环、跳转等语句都需要依赖PC来完成。
由于多线程之间是通过时间片轮转来占用CPU资源,所以每一个线程都有自己独立的程序计数器,各线程独立存储,互不影响,因此,这一小块内存是线程私有的。
需要注意一点:如果线程执行的是java方法,那么PC记录的是正在执行的字节码指令地址;而如果正在执行的是Native方法(本地方法,实现不是由java语言完成的),那么PC值为空。
2. Java虚拟机栈
虚拟机栈就是我们常说的内存中的栈空间,也是线程私有的,生命周期与线程相同,是为字节码(Java方法)服务的,用来支持java方法的执行。
虚拟机栈里存放的元素是栈帧(用以存放局部变量表、操作栈、动态链接、方法返回值、附加信息等),每一个方法从调用直到执行完成,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。java方法是基于栈的执行引擎,这里的栈指的就是栈帧中的操作栈。
栈帧的结构重点是局部变量表和操作栈,其余都属于栈帧信息。需要注意的是,栈帧中需要多大的局部变量表,多大的操作栈,这些都是在编译时就确定的,存在了方法表的Code属性中,运行时不会改变。
局部变量表用以存放方法的参数和内部定义的局部变量,基本单位是slot(变量槽,一般是32位),64位的long和double会占据两个连续的slot。局部变量表的开头存放的是参数,对于实例方法,第0位索引的slot默认是this参数,后续依次是其他参数。参数表之后是内存定义的其他局部变量。
操作栈是java方法执行所依赖的基本结构,各种字节码指令都是通过向操作栈中写入和提取内容来完成相应的运算或者调用其他的方法。所有的运算过程,都以操作栈的出栈和入栈作为信息交换的途径。
3. 本地方法栈
本地方法栈和虚拟机栈是完全相同的,唯一的差别是本地方法栈是为native方法服务,有的虚拟机将这两部分合二为一,有的分成两部分实现,本质上没有差别。
4. Java堆
堆空间是虚拟机所管理内存中最大的一块,所有的对象实例以及数组都在堆上分配(简单理解就是一般所有new出来的都在堆空间中),由虚拟机启动时创建,所有线程共享这一块区域。
Java堆不一定物理上连续,逻辑上连续即可。更重要的一点是,Java堆是垃圾收集器管理的主要区域,因此也被称为“GC堆”。现在的垃圾收集器一般都采用分代收集算法,也就是为了更好对内存进行回收,进一步将堆空间划分为:新生代和老年代。新生代更进一步可以划分为:Eden空间、From Survivor空间和To Survivor空间。
5. 方法区
方法区又称为“永久代”,类似于堆空间,是所有线程共享的内存区域,用以存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
方法区同样可以不一定在物理上连续,这一块区域可以实现垃圾收集,也可以不实现,或者直接将堆空间的垃圾收集机制扩展到方法区即可。原因是,这块区域的回收目标主要是常量池的回收和对类型的卸载,这个区域很少情况下需要回收,这也是被称为“永久代”的原因。
方法区中很重要的一部分是运行时常量池,用于存放在编译期生成的各种字面量和符号引用,在类加载完成后进入方法区的运行时常量池中存放。其中,字面量很好理解,比如文本字符串、声明为final的常量值等,而符号引用主要指的是以下三类:类和接口的全限定名,字段的名称和描述符,方法的名称和描述符。
6. 直接内存
直接内存不是虚拟机运行时数据区的一部分,是jdk1.4以后引入的一种基于通道和缓冲区的I/O方式,可以使用native本地函数库直接分配堆外内存。
【深入理解Java虚拟机】自动内存管理机制——内存区域划分的更多相关文章
- 《深入理解 Java 虚拟机》学习 -- 类加载机制
<深入理解 Java 虚拟机>学习 -- 类加载机制 1. 概述 虚拟机把描述类的数据从 Class 文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的 J ...
- [深入理解Java虚拟机]<自动内存管理>
Overview 走近Java:介绍Java发展史 第二部分:自动内存管理机制 程序员把内存控制的权利交给了Java虚拟机,从而可以在编码时享受自动内存管理.但另一方面一旦出现内存泄漏和溢出等问题,就 ...
- 深入理解Java虚拟机:垃圾收集器与内存分配策略
目录 3.2 对象已死吗 判断一个对象是否可被回收 引用类型 finalize() 回收方法区 3.3. 垃圾收集算法 1.Mark-Sweep(标记-清除)算法 2.Copying(复制)算法 3. ...
- 《深入理解Java虚拟机》学习笔记之内存分配
JVM在执行Java程序的过程中会把它所管理的内存划分若干个不同的数据区域,如下图: 大致可以分为两类:线程私有区域和线程共享区域. 线程私有区域 程序计数器(Program Counter Regi ...
- 深入理解Java虚拟机一:运行时数据区域
根据<Java虚拟机规范(第2版)>的规定,Java虚拟机管理的内存包括下图几个运行时数据区域: 1.程序计数器 程序计数器(Program Counter Register ...
- 深入理解JAVA虚拟机 自动内存管理机制
运行时数据区域 其中右侧三个一起的部分是每个线程一份,左侧两个是所有线程共享的. 程序计数器(Program Counter Register) 英文名称叫Program Counter Regist ...
- 深入理解Java虚拟机二:垃圾收集与内存分配
垃圾收集:垃圾收集要完成三件事,包括哪些内存需要回收,什么时候回收及如何回收. 1.需要回收的内存判定:没有引用指向原先分配给某个对象的内存时,则该内存是需要回收的垃圾 Java垃圾收集器在对内存进行 ...
- 《深入理解java虚拟机》读书笔记1--java内存区域
Java内存管理 本文主要介绍Java虚拟机运行时的内存区域是如何划分的.Java对象的创建过程.Java对象的内存布局.Java对象的访问定位 一:运行时区域划分 主要可以分为以下 几个: 程序计数 ...
- 深入理解Java虚拟机笔记——垃圾收集器与内存分配策略
目录 判断对象是否死亡 引用计数器算法 可达性分析算法 各种引用 回收方法区 垃圾收集算法 标记-清除算法 复制算法 标记-整理算法 分代收集算法 HotSpot算法实现 枚举根节点 GC停顿(Sto ...
随机推荐
- 生成PW配置和BFD配置
保存在配置文件中 def Main(): buf = '' f = open('pw.cfg','w') for i in range(2016): pwid = str(102 + i) buf + ...
- ExtJs之gridPanel的属性表格,编辑表格,表格分页,分组等技巧
这里藏的配置确实多.. 慢慢实践吧. <!DOCTYPE html> <html> <head> <title>ExtJs</title> ...
- DJANGO之自定义模板过滤器
我查找了DJANGO模板的过滤器,好像指定字符串包含指定关-键字符的过滤器没有呢, 没有硬着头-皮,按网上其它人的作法,写了一个,成功了...:) 参考URL: http://liuzhijun.it ...
- Docker--在ubuntu中的操作
docker的基础命令 安装前的检查 //查看内核版本 uname -a //检查Device Mapper ls -l /sys/class/misc/device-mapper 在ubuntu中安 ...
- 自己主动化的在程序中显示SVN版本号
有时候会有这种情况,策划拿着应用过来提一个bug,但我们却不好确定策划的手机上装的应用相应的是那个代码版本号. 为了解决问题.我们希望能在应用上显示出当前应用所相应的代码版本号,即svn版本号. 构想 ...
- Aizu/Aoj 0121 Seven Puzzle
这题应该算是经典的八数码问题的弱化版吧:给你一个4x2的方版,上面有0-7 八个数字,每次只能让编号0的方格跟他的上下左右的方格交换:所以也就是把方格0当做空格看待,每次只有空格周围的方格能够向空格处 ...
- [Java][Android][Process] Process 创建+控制+分析 经验浅谈
不管是Android亦或者Java中或多或少须要调用底层的一些命令.运行一些參数: 此时我们须要用到Java的Process来创建一个子进程.之所以是子进程是由于此进程依赖于发起创建请求的进程,假设发 ...
- vim插件系列
http://foocoder.com/blog/mei-ri-vimcha-jian-ping-hua-gun-dong-accelerated-smooth-scroll-dot-vim.html ...
- Unsupported major.minor version 52.0 (unable to load class XXX
java项目构建从高版本JDK改为低版本JDK报错.这是再次编译时使用的JDK版本比你原来编译的版本低所导致的. 转自:http://blog.csdn.net/zixiao217 maven项目在服 ...
- php 判断字符串包含中文(转)
$str = "测试中文"; echo $str; echo "<hr>"; //if (preg_match("/^[".ch ...