Java8-JVM内存区域划分白话解读
前言
java作为一款能够自动管理内存的语言,与传统的c/c++语言相比有着自己独特的优势。虽然我们无需去管理内存,但为了防范可能发生的异常,我们需要对java内部数据如何存储有一定了解,已应对突发问题,写出更好的程序
JVM对运行时程序内存的划分
java程序在被编译成字节码后,由JVM执行,执行期间产生的所有数据,会被分门别类的存储在JVM预设好的区域里,具体情况如下所示
java6时方法区还属于JVM管理的内存,那时俗称为“永久代”,负责存储:被虚拟机加载的类型信息、方法信息、常量(包括字符串常量)、静态变量等等
java7时把永久代里的字符串常量池、静态变量移动到了堆中
java8废除永久代,改用元空间来实现方法区,原来java7中永久代的剩余内容移动到元空间中
以下为java8的内存分布图

Tips:红色是线程共享的,黄色是线程私有的
接下来我们着重讨论Java8中的内存分布情况
JVM管理的内存
这部分内存在JVM中,由JVM直接分配,初始大小、最大大小都可以由JVM进行配置
程序计数器
是一段较小的内存空间,用于告诉字节码解释器下一条执行哪一个字节码指令。是唯一一个在《java虚拟机规范》没有规定任何OutOfMemoryError的区域
每条线程必须有独立的程序计数器,以确保切换线程时,线程可以在正确的位置继续执行字节码
Tips:当执行Native方法时,计数器值为空(undefined)
虚拟机栈
我们平常俗称的栈指的就是虚拟机栈,用来描述和存储Java方法的内存模型。里面的数据生命周期在编译时就已经确定了,比如局部变量方法调用结束就该释放,内存很容易管理,所以并不是很依赖GC
具体行为:
每当执行一个方法时,JVM就会创建一个栈帧放进虚拟机栈中


栈帧的内容包括但不限于:
- 局部变量表(也包括形参)
- 八大基本数据类型
- 引用类型(直接指针或者句柄,由具体的JVM实现决定)
- returnAddress类型 (用于方法结束回到原来的字节码位置继续执行)
- 操作数栈
- 开始时是空的,运行后逐渐入栈出栈,比如算数运算就是操作数栈进行的
- 动态连接
- 方法出口
直到方法执行结束,JVM就会将此方法的栈帧出栈
显然,如果多个线程共用同一虚拟机栈,会出现某个线程的方法还没执行完毕,又被另一线程的栈帧入栈,破坏了方法数据结构。所以虚拟机栈是线程私有的
returnAddress作用
用于执行完方法后回到调用方法的位置继续往下执行
当一个栈帧入栈时,returnAddress保存当前程序计数器的值,即当前字节码位置,然后开始执行方法,方法执行结束后,用returnAddress的值恢复程序计数器,即回到调用方法时的字节码位置
本地方法栈
几乎与虚拟机栈一样的作用,其区别是,本地方法栈为本地Native方法服务,通常是本地的C/C++库的方法,而虚拟机栈是为java方法服务的
堆区
通常是JVM中最大的内存区域,也是垃圾收集器GC最经常光顾的区域,里面的数据生命周期无法在编译时确定,需要GC来帮助判断是否是“死亡变量”,以回收没必要的内存。
存储的内容:
- 对象的实例
- 数组
- 字符串常量池
- 物理上在堆区,逻辑上是方法区的内容
- 静态变量
- 物理上在堆区,逻辑上是方法区的内容
本地内存
默认情况使用大小只受限于本地内存的实际大小
但我们任可以通过JVM配置限制使用大小
这里面的数据一般不经常变动,存放在这里被JVM间接管理较为合适(间接管理速度肯定比JVM内部的慢些)
方法区(元空间)
java8使用元空间来实现的方法区,《Java虚拟机规范》中方法区为堆区的逻辑部分,堆中的对象依靠方法区存储的类信息来生成实例
存储的内容:
- 运行时常量池
- 字面量
- 符号引用
- 类信息
- 类型
- 完整名
- 修饰符
- 父类、接口信息
- 域
- 名称
- 类型
- 方法
- 名称
- 参数
- 返回值
- 字节码
- 类型
以上包含了一些有代表性的内容,并不代表方法区存储的全部内容
直接内存
此部分并不常用,至少对我目前来说。
在jdk1.4中加入了NIO(New Input/Putput)类,引入了一种基于通道(channel)与缓冲区(buffer)的新IO方式,它可以使用native函数直接分配堆外内存,然后通过存储在java堆中的DirectByteBuffer对象作为这块内存的引用进行操作,这样可以在一些场景下大大提高IO性能,避免了在java堆和native堆来回复制数据。--《深入理解java虚拟机》
Java8-JVM内存区域划分白话解读的更多相关文章
- JVM内存区域划分及垃圾回收
第一部分.闲扯+概述 近来在研读<深入理解java虚拟机>一书,读完之后做个小结,算是记录一下自己的学习所得,在成长的路上,只能死磕. 要理解JVM,就要先从其内存区域划分开始,知道其由几 ...
- JVM内存区域划分
前言 Java程序的运行是通过Java虚拟机来实现的.通过类加载器将class字节码文件加载进JVM,然后根据预定的规则执行.Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同 ...
- JVM内存区域划分(JDK6/7/8中的变化)
前言 Java程序的运行是通过Java虚拟机来实现的.通过类加载器将class字节码文件加载进JVM,然后根据预定的规则执行.Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同 ...
- JVM内存区域划分Eden Space、Survivor Space、Tenured Gen,Perm Gen解释
以下内容转自:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=29632145&id=4616836 jvm区域总体分两 ...
- JVM内存区域划分Eden Space、Survivor Space、Tenured Gen,Perm Gen解释(转)
jvm区域总体分两类,heap区和非heap区.heap区又分:Eden Space(伊甸园).Survivor Space(幸存者区).Tenured Gen(老年代-养老区). 非heap区又分: ...
- JVM内存区域划分Eden Space,Survivor Space,Tenured Gen,Perm Gen
jvm区域总体分两类,heap区和非heap区.heap区又分:Eden Space(伊甸园).Survivor Space(幸存者区).Tenured Gen(老年代-养老区). 非heap区又分: ...
- JVM内存区域划分总结
发现网上有两个版本的JVM内存划分,一个是按照<深入理解JVM虚拟机>上的版本,包含程序计数器等,按照是否线程共享划分. 另一个我觉得更好记一些,也更适合我自己,在这里记录一下. 首先上思 ...
- [转]JVM内存区域划分Eden Space、Survivor Space、Tenured Gen,Perm Gen解释
jvm区域总体分两类,heap区和非heap区.heap区又分:Eden Space(伊甸园).Survivor Space(幸存者区).Tenured Gen(老年代-养老区). 非heap区又分: ...
- JVM 内存区域划分
一.运行时数据区包括哪几部分? 根据<Java虚拟机规范>的规定,运行时数据区通常包括这几个部分:程序计数器(Program Counter Register).Java栈(VM Stac ...
随机推荐
- pip安装加速
PIP国内镜像源 名称 源地址 阿里云 http://mirrors.aliyun.com/pypi/simple/ 中国科技大学 https://pypi.mirrors.ustc.edu.cn/s ...
- bzoj2460元素(线性基,贪心)
题目大意: 给定\(n\)个二元组\((a,b)\),求一个最大的\(\sum b\)的集合,满足这个集合的任意子集的\(a\)的\(xor\)值不为0 这道题需要一个线性基的性质: 线性基的任何非空 ...
- Python&Selenium 数据驱动测试【unittest+ddt+xml】
一.摘要 本博文将介绍Python和Selenium做自动化测试时,基于unittest框架,借助ddt模块,使用xml文件作为测试输入. 二.xml文件 保存路径:D:\\Programs\\Pyt ...
- 【UE4 C++】编程子系统 Subsystem
概述 定义 Subsystems 是一套可以定义.自动实例化和释放的类的框架.可以将其理解为 GamePlay 级别的 Component 不支持网络赋值 4.22开始引入,4.24完善.(可以移植源 ...
- 生产环境全链路压测平台 Takin
什么是Takin? Takin是基于Java的开源系统,可以在无业务代码侵入的情况下,嵌入到各个应用程序节点,实现生产环境的全链路性能测试,适用于复杂的微服务架构系统. Takin核心原理图 Taki ...
- 求求你了,用Docker吧
这是一个开始使用 Docker 的 Tutorial 大无语事件发生!大数据课实验课要用到Hadoop,实验指导是在一个Ubuntu虚机上通过安装包安装Hadoop并运行一个词频统计程序,整个实验就是 ...
- 【二食堂】Alpha - Scrum Meeting 11
Scrum Meeting 11 例会时间:4.21 18:00~18:20 进度情况 组员 进度 今日任务 李健 1. 登录注册页面前后端对接issue 1. 登录注册页面前后端对接issue2. ...
- 一套比较好用的公众号UI框架-weui
最近工作原因 需要在pd端弄一套js类似bootstrap框架 由于使用环境是在公众号终端用的比较多! 类似上面这样的样式 所以我从微信官方开始找起 最后找到了WEUI 还别说 真的挺好用的 这是大佬 ...
- 转:SYNOPSYS VCS Makefile文件编写与研究
SYNOPSYS VCS Makefile文件编写与研究 这个Makefile是synopsys提供的模板,看上去非常好用,你只要按部就班提供实际项目的参数就可以了.我们来看这个文件的头部说明:mak ...
- linux c语言 rename的用法-rename() does not work across different mount points, even if the same file system is mounted on both
最近在一个项目上执行文件的搬移功能时发现总是失败,临时录像文件存放于emmc的/tmp/目录下,当录像完成时候则调用rename企图将此文件搬到/mnt/sdcard/mmcblk1p1/(这是外置的 ...