JVM运行时数据区

Java虚拟机所管理的内存区域,也称为运行时数据区,分为以下几个运行时数据区,如图所示

程序计数器:当前程序所执行字节码的行号指示器

程序计数器(Program Counter Register)是一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器。在虚拟机的概念模型里,字节码解释器工作时就是通过改变这个计数器的值来选 取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需 要依赖这个计数器来完成。

Java虚拟机的多线程是是通过线程轮流切换并分配处理器执行时间的方式来实现的,在任何时刻,一个处理器(对于多核处理器来说是一个核)都只会执行一条程序中的指令。因此为了切换后能恢复到正常的位置,每个线程都应该有一个独立的程序计数器,各线程之间计数器互补影响,独立存储,因此称这类区域为**“线程私有“内存**。

如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是Native方法,这个计数器值则为空(Undefined)此内存区域 是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域。

Java虚拟机栈:Java方法执行的内存模型:栈帧的入栈与出栈

与程序计数器一样,Java虚拟机栈(Java Virtual Machine Stacks)也是私有的,它的生命周期与线程相同。

虚拟机栈描述的是Java方法执行的内存模型:每个方法在执行的同时会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等。每一个方法从调用直至完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈。

经常说的**堆内存(Heap)和栈内存(Stack)**中栈内存指的就是虚拟机栈,或者说是虚拟机栈中局部变量表部分。

局部变量表存放了编译期可知的各种数据类型(boolean、byte、char、short、int、float、long、double)、对象引用(reference类型)和returnAddress类型(指向了一条字节码指令的地址)。

本地方法栈:执行本地方法

本地方法栈(Native Method Stack)与虚拟机栈所发挥的作用是非常相似,之间的区别是,虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机用到的Native方法服务

Java堆:存放对象及数组实例

对于大多数应用来说,Java堆(Java Heap)是Java虚拟机所管理的内存中最大的一块内存。Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。Java堆的唯一目的就是存放对象的实例,几乎所有的对象实例都在这里分配内存。这一点在Java虚拟机规范中的描 述是:所有的对象实例以及数组都要在堆上分配。随着JIT编译器的发展与逃逸分析技术的主键成熟,栈上分配、标量替换优化技术将会导致一些微妙的变化发生,所有的对象都 分配在堆上也渐渐变得不是那么“绝对”了。

Java堆是垃圾收集器管理的主要区域,因此也常被称为GC堆(Garbage Collected Heap)

方法区:存储虚拟机加载的类信息,常量,静态变量和编译后的代码

方法区(Method Area)与Java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据

这个区域的内存回收主要是针对常量池的回收和针对类型的卸载。

运行时常量池:方法区的一部分,存放编译器生成的各种字面量和符号引用

运行时常量池(Runtime Constant Pool)是方法区的一部分。Class文件中除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池(Constant Pool Table),用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池中存放。

Java虚拟机对Class文件的每一部分(也包括常量池)的格式都有严格规定,每一个字节用于存储那种数据都必须符合规范上的要求才会被虚拟机认可、装载和执行,但对运行时常量池,Java虚拟机规范没有做任何细节的要求,不同的提供厂商可以按自己的需要来实现这个区域。(除了符号引用,直接引用也存储在运行时常量池中)

Java虚拟机中的每个运行时数据区都有各自的功能,有线程隔离的也有线程共享,以下各个Java虚拟机运行时数据区的具体功能、线程共享还是线程隔离及可能抛出的异常的总结:

除次之外,java也可以通过本地方法直接分配对外内存,这部分内存也称之为直接内存。**直接内存(Direct Memory 本机直接内存)**不是虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域。但这部分内存也别频繁地使用,也可能导致OutOfMemeoryError异常。

在JDK 1.4中新加入了NIO(New Input/Output)类,引入了一种基于通道(Channel)与缓 冲区(Buffer)的I/O方式,它可以使用Native函数库直接分配堆外内存,然后通过一个存储在Java堆中的DirectByteBuffer对象作为这块内存的引用进行操作。这样能在一些场景中显著提高性能,因为避免了在Java堆和Native堆中来回复制数据。

对象在内存中初始化的过程

public class Person{
String name;
int age;
}

在main方法中,创建对象时,在JVM中分配内存的过程如下图

首先类加载器从硬盘加载字节码(.class)文件,被虚拟机加载的类信息、常量、静态变量、即使编译器编译后的代码等数据存储在方法区,main方法(栈帧)压入java虚拟机栈,创建对象时,对象的引用存储在栈帧中的局部变量表中,而具体的对象在堆中分配内存。

JVM运行时数据区及对象在内存中初始化的过程的更多相关文章

  1. JVM内存结构/JVM运行时数据区,以及堆内存的划分

    1.程序计数器: 程序计数器是线程私有的内存,JVM多线程是通过线程轮流切换并分配处理器执行时间的方式实现的,当线程切换后需要恢复到正确的执 行位置(处理器)时,就是通过程序计数器来实现的.此内存区域 ...

  2. Jvm运行时数据区

    一:运行时数据区 Java虚拟机在执行Java程序的过程中会把它管理的内存分为若干个不同的数据区域.这些区域有着各自的用途,一级创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域则依赖用户 ...

  3. Java内存管理:Java内存区域 JVM运行时数据区

    转自:https://blog.csdn.net/tjiyu/article/details/53915869 下面我们详细了解Java内存区域:先说明JVM规范定义的JVM运行时分配的数据区有哪些, ...

  4. JVM 运行时数据区 (三)

    JVM运行时数据区 运行时数据区由 程序计数器.java虚拟机栈.本地方法栈.堆.方法区 组成: 1.程序计数器 每一个Java线程都有一个程序计数器,用于保存程序执行到当前方法的哪一个指令,它是线程 ...

  5. JVM总结(一):概述--JVM运行时数据区

    大三下,趁着寒假重温一遍JVM,准备在一个系列来总价一下学习JVM的整个过程.争取在接下来的一个星期内更新完这一个系列,然后回家过年. JVM运行时数据区 线程私有的数据区 程序计数器 虚拟机栈 本地 ...

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

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

  7. JVM运行时数据区和垃圾回收机制

    最近参考各种资料,尤其是<深入理解Java虚拟机 JVM高级特性和最佳实践>,大牛之作.把最近学习的Java虚拟机组成和垃圾回收机制总结一下. 你不会的都是新知识,学无止境,每天进步一点点 ...

  8. Java中的字符串常量池和JVM运行时数据区的相关概念

    什么是字符串常量池 JVM为了减少字符串对象的重复创建,其维护了一个特殊的内存,这段内存被成为字符串常量池或者字符串字面量池 工作原理 当代码中出现字面量形式创建字符串对象时,JVM首先会对这个字面量 ...

  9. JVM 运行时数据区(二)

    @ 目录 运行时数据区 共享区 堆区 方法区 隔离区 虚拟机栈 栈帧 本地方法栈 程序计数器 运行时数据区 JVM 运行时数据区主要分为5块 方法区 JDK1.8以后叫做元数据区(Metaspace) ...

随机推荐

  1. kaggle-制作评分卡

    https://blog.csdn.net/zpxcod007/article/details/80118580 制作A卡,申请评分卡 数据集:15万个样本,特征 主要预处理手段:缺失值,异常值,样本 ...

  2. Selenium:八种元素定位方法

    前言: 我们在做WEB自动化时,最根本的就是操作页面上的元素,首先我们要能找到这些元素,然后才能操作这些元素.工具或代码无法像我们测试人员一样用肉眼来分辨页面上的元素.那么我们怎么来定位他们呢? 在学 ...

  3. 从0开始的InfiniBand硬件踩坑过程

    由于科学计算实验的需求,需要使用InfiniBand做一个持久性内存全互联的分布式存储系统.其中从网卡到交换机使用Mellanox全家桶,而在Mellanox网卡与交换机的使用过程中还是遇到了不少的问 ...

  4. 48-python基础-python3-字符串-常用字符串方法(六)-strip()-rstrip()-lstrip()

    7-用 strip().rstrip()和 lstrip()删除空白字符 strip()字符串方法将返回一个新的字符串,它的开头或末尾都没有空白字符. lstrip()和 rstrip()方法将相应删 ...

  5. android Manifest.xml 文件详解

  6. c# 微服务Ocelot网关服务发现

    前面提到微服务方案,介绍了该东西,推荐一篇介绍博文https://www.cnblogs.com/jesse2013/p/net-core-apigateway-ocelot-docs.html 我要 ...

  7. 【转】优秀的Vue UI组件库

    原文来源:https://www.leixuesong.com/3342 Vue 是一个轻巧.高性能.可组件化的MVVM库,API简洁明了,上手快.从Vue推出以来,得到众多Web开发者的认可.在公司 ...

  8. 使用while循环实现菜单

  9. 拓展练习--find查找、打包压缩、服务器、磁盘挂载

    目录 find查找.打包压缩 服务器部分 磁盘挂载及单用户模式 find查找.打包压缩 1.超级用户(管理员用户)提示符是_#,普通用户提示符是$_. 2.如何快速返回上一次所在的目录? cd - 3 ...

  10. 2019牛客暑期多校训练营(第九场)A.The power of Fibonacci

    题意:给出n和m,f(n)是斐波那契额数列的第n项,要求计算ans=f(1)^m+f(2)^m+....f(n)^m.即斐波那契额数列前n项的m次幂和. 解法:这题好像有两种解法:一种是循环节+CRT ...