前言

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就会创建一个栈帧放进虚拟机栈中

栈帧的内容包括但不限于:

  1. 局部变量表(也包括形参)

    • 八大基本数据类型
    • 引用类型(直接指针或者句柄,由具体的JVM实现决定)
    • returnAddress类型 (用于方法结束回到原来的字节码位置继续执行)
  2. 操作数栈
    • 开始时是空的,运行后逐渐入栈出栈,比如算数运算就是操作数栈进行的
  3. 动态连接
  4. 方法出口

直到方法执行结束,JVM就会将此方法的栈帧出栈

显然,如果多个线程共用同一虚拟机栈,会出现某个线程的方法还没执行完毕,又被另一线程的栈帧入栈,破坏了方法数据结构。所以虚拟机栈是线程私有的

returnAddress作用

用于执行完方法后回到调用方法的位置继续往下执行

当一个栈帧入栈时,returnAddress保存当前程序计数器的值,即当前字节码位置,然后开始执行方法,方法执行结束后,用returnAddress的值恢复程序计数器,即回到调用方法时的字节码位置


本地方法栈

几乎与虚拟机栈一样的作用,其区别是,本地方法栈为本地Native方法服务,通常是本地的C/C++库的方法,而虚拟机栈是为java方法服务的


堆区

通常是JVM中最大的内存区域,也是垃圾收集器GC最经常光顾的区域,里面的数据生命周期无法在编译时确定,需要GC来帮助判断是否是“死亡变量”,以回收没必要的内存。

存储的内容:

  1. 对象的实例
  2. 数组
  3. 字符串常量池
    • 物理上在堆区,逻辑上是方法区的内容
  4. 静态变量
    • 物理上在堆区,逻辑上是方法区的内容

本地内存

默认情况使用大小只受限于本地内存的实际大小

但我们任可以通过JVM配置限制使用大小

这里面的数据一般不经常变动,存放在这里被JVM间接管理较为合适(间接管理速度肯定比JVM内部的慢些)

方法区(元空间)

java8使用元空间来实现的方法区,《Java虚拟机规范》中方法区为堆区的逻辑部分,堆中的对象依靠方法区存储的类信息来生成实例

存储的内容:

  1. 运行时常量池

    • 字面量
    • 符号引用
  2. 类信息
    • 类型

      • 完整名
      • 修饰符
      • 父类、接口信息
      • 名称
      • 类型
    • 方法
      • 名称
      • 参数
      • 返回值
      • 字节码

以上包含了一些有代表性的内容,并不代表方法区存储的全部内容


直接内存

此部分并不常用,至少对我目前来说。

在jdk1.4中加入了NIO(New Input/Putput)类,引入了一种基于通道(channel)与缓冲区(buffer)的新IO方式,它可以使用native函数直接分配堆外内存,然后通过存储在java堆中的DirectByteBuffer对象作为这块内存的引用进行操作,这样可以在一些场景下大大提高IO性能,避免了在java堆和native堆来回复制数据。--《深入理解java虚拟机》


Java8-JVM内存区域划分白话解读的更多相关文章

  1. JVM内存区域划分及垃圾回收

    第一部分.闲扯+概述 近来在研读<深入理解java虚拟机>一书,读完之后做个小结,算是记录一下自己的学习所得,在成长的路上,只能死磕. 要理解JVM,就要先从其内存区域划分开始,知道其由几 ...

  2. JVM内存区域划分

    前言 Java程序的运行是通过Java虚拟机来实现的.通过类加载器将class字节码文件加载进JVM,然后根据预定的规则执行.Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同 ...

  3. JVM内存区域划分(JDK6/7/8中的变化)

    前言 Java程序的运行是通过Java虚拟机来实现的.通过类加载器将class字节码文件加载进JVM,然后根据预定的规则执行.Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同 ...

  4. JVM内存区域划分Eden Space、Survivor Space、Tenured Gen,Perm Gen解释

    以下内容转自:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=29632145&id=4616836 jvm区域总体分两 ...

  5. JVM内存区域划分Eden Space、Survivor Space、Tenured Gen,Perm Gen解释(转)

    jvm区域总体分两类,heap区和非heap区.heap区又分:Eden Space(伊甸园).Survivor Space(幸存者区).Tenured Gen(老年代-养老区). 非heap区又分: ...

  6. JVM内存区域划分Eden Space,Survivor Space,Tenured Gen,Perm Gen

    jvm区域总体分两类,heap区和非heap区.heap区又分:Eden Space(伊甸园).Survivor Space(幸存者区).Tenured Gen(老年代-养老区). 非heap区又分: ...

  7. JVM内存区域划分总结

    发现网上有两个版本的JVM内存划分,一个是按照<深入理解JVM虚拟机>上的版本,包含程序计数器等,按照是否线程共享划分. 另一个我觉得更好记一些,也更适合我自己,在这里记录一下. 首先上思 ...

  8. [转]JVM内存区域划分Eden Space、Survivor Space、Tenured Gen,Perm Gen解释

    jvm区域总体分两类,heap区和非heap区.heap区又分:Eden Space(伊甸园).Survivor Space(幸存者区).Tenured Gen(老年代-养老区). 非heap区又分: ...

  9. JVM 内存区域划分

    一.运行时数据区包括哪几部分? 根据<Java虚拟机规范>的规定,运行时数据区通常包括这几个部分:程序计数器(Program Counter Register).Java栈(VM Stac ...

随机推荐

  1. Serverless 在 SaaS 领域的最佳实践

    作者 | 计缘 来源 | Serverless 公众号 随着互联网人口红利逐渐减弱,基于流量的增长已经放缓,互联网行业迫切需要找到一片足以承载自身持续增长的新蓝海,产业互联网正是这一宏大背景下的新趋势 ...

  2. 题解 「2017 山东一轮集训 Day5」苹果树

    题目传送门 题目大意 给出一个 \(n\) 个点的图,每个点都有一个权值 \(f_i\) ,如果 \(f_i=-1\) 表示 \(i\) 这个点是坏的.定义一个点是有用的当且仅当它不是坏的,并且它连的 ...

  3. Framework - 性能统计

    摘要 近期对接客户时,客户方希望提供 SDK 的性能.内存.隐私支持等一些数据,所以就对 SDK 进行了一些性能测试. 在用表格统计整理这些数据时,突然发现,经常用统计的方式看 SDK 的相关数据,似 ...

  4. js--Symbol 符号基本数据类型

    前言 ECMAScript 6 中新增了 Symbol 符号这一基本数据类型,那么Symbol 是用来干什么的,对开发又有什么帮助呢?本文来总结记录一下 Symbol 的相关知识点. 正文 Symbo ...

  5. 脚本注入2(post)

    终于写到非get类型的注入了. 不过,我懒得在这里搞代码审计了:留到存储型XSS原型的时候再来分析源码吧. 这次以Less-15为例. 框里随便输点东西,submit,抓包,发现包出现了一些改变: 同 ...

  6. Python绘制Excel图表

    今天讲解下如何使用Python绘制各种Excel图表,下面我们以绘制饼状图.柱状图.水平图.气泡图.2D面积图.3D面积图为例来说明. import openpyxlfrom openpyxl imp ...

  7. Spring DeferredResult 异步请求

    Spring DeferredResult 异步请求 一.背景 二.分析 三.实现要求 四.后端代码实现 五.运行结果 1.超时操作 2.正常操作 六.DeferredResult运行原理 六.注意事 ...

  8. AlertManager集群搭建

    AlertManager集群搭建 一.AlertManager集群搭建 1.背景 2.机器 3.集群可用配置 4.alertmanager启动脚本 1.127.0.0.1:9083 机器启动脚本 2. ...

  9. 高斯消元de小板几

    感觉就是模拟解方程,还比手动解方程笨一些.... 但是大数据的话,他毕竟比我解得快多了.... 1 inline int Gauss(int n){ 2 int cnt=1;//真实到达的行列式行数 ...

  10. 攻防世界 杂项 6.pure_color

    图片隐写 工具 使用StegSolve一把梭 另一种解法 右击图片编辑,画图工具打开,属性设置黑白.