JVM内存划分
来源:互联网 发布:淘宝如何加入放心淘 编辑:程序博客网 时间:2024/05/01 07:31
从上图可以看出,JVM内存区域可以简单的划分为方法区,堆区,虚拟机栈,本地方法栈和程序计数器。上图中,浅色的为线程共有的内存区域,深色的为线程私有的内存区域。
可以看出,方法区和堆区是所有线程之间共享的内存区,而栈区和pc则是线程本身私有的,不能被其他线程所共享。我们简单的说下各个区域:
程序计数器:学过组成原理和操作系统的话,我们都知道其中有一个PC,用来告诉cpu运行什么指令。在JVM中,也是类似的,只不过这里的指令不是操作系统级别,而是JVM的,它可以看作当前线程所执行的字节码的行号指示器。每个线程都有一个程序计数器去执行下一个执行指令的地址。此pc不包括native方法。这是唯一一个没有内存溢出异常的内存区域。
虚拟机栈:线程私有的内存区域,其生命周期和线程自身保持一致,栈区描述的是线程内方法执行的内存模型,线程在执行方法的时候,都会创建一个栈帧,用于保存局部变量表,操作数栈,动态链接,方法出口等信息。每次的方法调用都对应着一个栈帧在虚拟机栈的入栈和出栈操作。局部变量表存放了各种编译期可知的局部变量,如基本类型和对象引用等。局部变量表的内存空间在编译期间完成内存分配,当进入一个方法时,此方法所需栈帧的局部变量大小是确定的,不会在运行期间改变。这里引用下葛一鸣书中的定义:局部变量表是栈帧的重要组成部分之一,用于保存函数的参数,函数内部的局部变量等。局部变量表中的变量只在当前函数有效,当函数的调用结束后,随着局部变量表的销毁而销毁。
周志明书中说到,局部变量表的内存大小在编译器就已经决定了这是可以理解的,至少在编译器,我们就已经知道了函数的形参类型,方法内部的变量个数 等等,完全可以决定内存大小。
本地方法站栈:对应于native方法。
堆区:虚拟机内存中最大的一块区域。也是被所有线程共享的一块区域。此区域就是存放内存对象,几乎所有的对象实例都会在这里创建(少数在线程本地内存创建)。根据垃圾回收算法,堆区又可以细分为 新生代和老年代,其中新生代又分为Eden区和两个Survivor区。堆区上可以划分出TLAB(线程本地分配缓冲区)。
方法区:线程共享的内存区域,用于存储已经加载的类信息,常量,静态变量,即时编译后的代码数据等。JVM虚拟机规范把方法区描述为堆区的一个逻辑部分。在JDK1.6 和1.7中,方法区可以理解为Perm永久区,在JDK1.8中,永久区被彻底移除,取而代之的是元数据区,是一块堆外的直接内存。如果不指定大小,会耗尽JVM所有可用系统内存。
方法区还包含运行时常量池,用于存放运行时产生的常量。比如String.intern()方法。
直接内存:不是JVM虚拟机定义的内存区域,但也被频繁使用。比如NIO,引入了一种基于通道与缓冲区的IO方式,可以使用Native函数直接在堆外分配内存,然后通过堆中DiectByteBuffer作为这块内存的引用进行操作。
参考至周志明 葛一鸣书籍。
- JVM内存区域划分
- JVM内存划分
- 浅析JVM内存划分
- 学习JVM:内存划分
- jvm内存区域划分
- JVM内存划分
- JVM内存区域划分
- jvm 内存区域划分
- JVM内存区域划分
- JVM的内存划分
- JVM内存划分
- JVM内存划分
- jvm内存区域划分
- JVM内存区域划分
- JVM虚拟机-内存划分
- JVM内存划分
- JVM的内存划分
- jvm内存划分
- C++虚函数多态
- bootstrap分页
- 1012 数字分类 PAT
- h5学习笔记(2)this 、循环赋值引用问题
- Linux内核版本信息获取
- JVM内存划分
- bootstrap按钮组(一)
- SVN:E175002 REPORT
- mysql中的触发器
- SpringMvc4+Mybatis整合
- [java]1、Long对象与long基本类型
- C51单片机学习(二):中断系统和定时器
- h2数据库多连接
- C++ 模板详解(二)