JVM内存模型

JVM内存模型可以分为两个部分,如下图所示,堆和方法区是所有线程共有的,而虚拟机栈,本地方法栈和程序计数器则是线程私有的。
 

1. 堆(Heap)

堆内存是所有线程共有的,可以分为两个部分:年轻代和老年代。下图中的Perm代表的是永久代,但是注意永久代并不属于堆内存中的一部分,同时jdk1.8之后永久代也将被移除。
堆是java虚拟机所管理的内存中最大的一块内存区域,也是被各个线程共享的内存区域,该内存区域存放了对象实例及数组(但不是所有的对象实例都在堆中)。其大小通过-Xms(最小值)和-Xmx(最大值)参数设置(最大最小值都要小于1G),前者为启动时申请的最小内存,默认为操作系统物理内存的1/64,后者为JVM可申请的最大内存,默认为物理内存的1/4,默认当空余堆内存小于40%时,JVM会增大堆内存到-Xmx指定的大小,可通过-XX:MinHeapFreeRation=来指定这个比列;当空余堆内存大于70%时,JVM会减小堆内存的大小到-Xms指定的大小,可通过XX:MaxHeapFreeRation=来指定这个比列,当然为了避免在运行时频繁调整Heap的大小,通常-Xms与-Xmx的值设成一样。堆内存 = 新生代+老生代+持久代。在我们垃圾回收的时候,我们往往将堆内存分成新生代和老生代(大小比例1:2),新生代中由Eden和Survivor0,Survivor1组成,三者的比例是8:1:1,新生代的回收机制采用复制算法,在Minor GC的时候,我们都留一个存活区用来存放存活的对象,真正进行的区域是Eden+其中一个存活区,当我们的对象时长超过一定年龄时(默认15,可以通过参数设置),将会把对象放入老生代,当然大的对象会直接进入老生代。老生代采用的回收算法是标记整理算法。

2. 方法区(Method Area)

方法区也称”永久代“,它用于存储虚拟机加载的类信息、常量、静态变量、是各个线程共享的内存区域。默认最小值为16MB,最大值为64MB(64位JVM由于指针膨胀,默认是85M),可以通过-XX:PermSize 和 -XX:MaxPermSize 参数限制方法区的大小。它是一片连续的堆空间,永久代的垃圾收集是和老年代(old generation)捆绑在一起的,因此无论谁满了,都会触发永久代和老年代的垃圾收集。不过,一个明显的问题是,当JVM加载的类信息容量超过了参数-XX:MaxPermSize设定的值时,应用将会报OOM的错误。参数是通过-XX:PermSize和-XX:MaxPermSize来设定的。

3.虚拟机栈(JVM Stack)

描述的是java方法执行的内存模型:每个方法被执行的时候都会创建一个”栈帧”,用于存储局部变量表(包括参数)、操作栈、方法出口等信息。每个方法被调用到执行完的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。声明周期与线程相同,是线程私有的。栈帧由三部分组成:局部变量区、操作数栈、帧数据区。局部变量区被组织为以一个字长为单位、从0开始计数的数组,和局部变量区一样,操作数栈也被组织成一个以字长为单位的数组。但和前者不同的是,它不是通过索引来访问的,而是通过入栈和出栈来访问的,可以看作为临时数据的存储区域。除了局部变量区和操作数栈外,java栈帧还需要一些数据来支持常量池解析、正常方法返回以及异常派发机制。这些数据都保存在java栈帧的帧数据区中。
局部变量表: 存放了编译器可知的各种基本数据类型、对象引用(引用指针,并非对象本身),其中64位长度的long和double类型的数据会占用2个局部变量的空间,其余数据类型只占1个。局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在栈帧中分配多大的局部变量是完全确定的,在运行期间栈帧不会改变局部变量表的大小空间。

4.本地方法栈(Native Stack)

与虚拟机栈基本类似,区别在于虚拟机栈为虚拟机执行的java方法服务,而本地方法栈则是为Native方法服务。(栈的空间大小远远小于堆)

5.程序计数器(PC Register)

是最小的一块内存区域,它的作用是当前线程所执行的字节码的行号指示器,在虚拟机的模型里,字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、异常处理、线程恢复等基础功能都需要依赖计数器完成。

6.直接内存

直接内存并不是虚拟机内存的一部分,也不是Java虚拟机规范中定义的内存区域。jdk1.4中新加入的NIO,引入了通道与缓冲区的IO方式,它可以调用Native方法直接分配堆外内存,这个堆外内存就是本机内存,不会影响到堆内存的大小.
 

Java:JVM的内存模型的更多相关文章

  1. java中JVM虚拟机内存模型详细说明

    java中JVM虚拟机内存模型详细说明 2012-12-12 18:36:03|  分类: JAVA |  标签:java  jvm  堆内存  虚拟机  |举报|字号 订阅     JVM的内部结构 ...

  2. Java对象的内存模型(一)

    前言 新人一枚,刚刚入门编程不久,各方面都在学习当中,博文有什么错误的地方,希望我们可以多多交流! 最近,在开发App后台过程中,需要将项目部署到云服务器上.而云服务器的内存大小却只有1G.要如何做到 ...

  3. java虚拟机的内存模型

    一.为什么要了解java虚拟机的内存模型 java虚拟机作为java代码运行的平台,是java技术的基石.了解java虚拟机的内存模型也就变得十分必要.它能帮助我们更好的了解java代码的运行机制,更 ...

  4. 面试官:别的我不管,这个JVM虚拟机内存模型你必须知道

    前言 说jvm的内存模型前先了解一下物理计算机的内存处理. 物理计算器上用户磁盘和cpu的交互,由于cpu读写速度速度远远大于磁盘的读写速度速度,所以有了内存(高速缓存区).但是随着cpu的发展,内存 ...

  5. JVM:内存模型

    JVM:内存模型 说明:这是看了 bilibili 上 黑马程序员 的课程 JVM完整教程 后做的笔记 1. java 内存模型 很多人将[java 内存结构]与[java 内存模型]傻傻分不清,[j ...

  6. 关于JAVA中的static方法、并发问题以及JAVA运行时内存模型

    一.前言 最近在工作上用到了一个静态方法,跟同事交流的时候,被一个问题给问倒了,只怪基础不扎实... 问题大致是这样的,“在多线程环境下,静态方法中的局部变量会不会被其它线程给污染掉?”: 我当时的想 ...

  7. Java虚拟机:内存模型详解

    版权声明:本文为博主原创文章,转载请注明出处,欢迎交流学习! 我们都知道,当虚拟机执行Java代码的时候,首先要把字节码文件加载到内存,那么这些类的信息都存放在内存中的哪个区域呢?当我们创建一个对象实 ...

  8. JVM运行时数据区与JVM堆内存模型小结

    前提 JVM运行时数据区和JVM内存模型是两回事,JVM内存模型指的是JVM堆内存模型. 那JVM运行时数据区又是什么? 它包括:程序计数器.虚拟机栈.本地方法栈.方法区.堆. 来看看它们都是干嘛的 ...

  9. 深入理解JAVA虚拟机(内存模型+GC算法+JVM调优)

    目录 1.Java虚拟机内存模型 1.1 程序计数器 1.2 Java虚拟机栈 局部变量 1.3 本地方法栈 1.4 Java堆 1.5 方法区(永久区.元空间) 附图 2.JVM内存分配参数 2.1 ...

随机推荐

  1. spring结合shiro的学习总结

    pom文件加入 <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-c ...

  2. linux input子系统详解

    首先,什么是linux的子系统: 输入子系统由驱动层.输入子系统核心.事件处理层三部分组成.一个输入事件,如鼠标移动通过Driver->Input core->Event handler- ...

  3. 记一次EFCore类型转换错误及解决方案

    一  背景 今天在使用EntityFrameworkCore 查询的时候在调试的时候总是提示如下错误:Unable to cast object of type 'System.Data.SqlTyp ...

  4. C 语言字符串的比较

    C 语言字符串的比较 #include <stdio.h> #include <Windows.h> #include <string.h> int main(vo ...

  5. apply,call和bind的使用及区别

    1.用途 1)apply,call和bind都是 用来改变this的指向 2)apply和call会让当前函数立即执行,而bind会返回一个函数,后续需要的时候再调用执行 2.this指向问题 thi ...

  6. core直接获取报异常数据

    报异常直接跳转到/Home/Error [ResponseCache(Duration = , Location = ResponseCacheLocation.None, NoStore = tru ...

  7. Gitlab Runner实现CI/CD自动化部署asp.net core应用

    环境说明 一台git服务器(192.168.169.7),安装gitlab,docker. 一台web服务器(192.168.169.6),安装git,gitlab runner,docker,dot ...

  8. Django学习笔记(二)App创建之Model

    通过实例学习, 构建一个投票(Polls)Application, 目标结果包含两个site, 一个site用来显示投票问题以及投票结果(即将展示出来的网站), 另一个site用来管理Poll实例的增 ...

  9. JavaScript,遍历,for

    (for循环,for...in ,for...of ,forEach)(:for in总是得到数组,字符串的下标,而for of和forEach一样,是直接得到值) (forEach() 方法用于调用 ...

  10. echarts使用结合时间轴timeline动态刷新案例

    1.echarts简介 ECharts,一个使用 JavaScript 实现的开源可视化库,可以流畅的运行在 PC 和移动设备上,兼容当前绝大部分浏览器(IE8/9/10/11,Chrome,Fire ...