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. selenium,webdriver爬取斗鱼主播信息 实操

    from selenium import webdriver import time from bs4 import BeautifulSoup class douyuSelenium(): #初始化 ...

  2. 数据库(四)—— Redis数据库

    目录 redis 一.redis的安装部署 二.redis配置文件 1.基本配置 2.安全配置 3.查看配置信息 三.redis持久化 1.持久化类型 2.RDB持久化 3.AOF持久化(append ...

  3. FlowProtal jQuery 对比时间大小

    function ValidatoTime(source, args){ var StartTime = agent.calcExpress(null, 'SCTDB:AS_MeetingRoom.S ...

  4. centos 7.2 离线安装 gcc

    1.查看有没有挂载 centos 7.2 的镜像源文件 2.如果没有就通过服务端挂载 如果不知怎么挂载,就解压CentOS-7-x86_64-DVD-1511.iso 镜像文件,在Packages找到 ...

  5. 三、python之文件的处理

    1.文件的读取 1.1 读取整个文件 假设我们有一个叫做“hello.txt”的文件,文件内容如下: helloWorld helloPython helloJava 在该文件中,有三行字符串,接下来 ...

  6. Netty 粘包 拆包 | 史上最全解读

    Netty 粘包/半包原理与拆包实战(史上最全) 疯狂创客圈 Java 聊天程序[ 亿级流量]实战系列之13 [博客园 总入口 ] 本文的源码工程:Netty 粘包/半包原理与拆包实战 源码 本实例是 ...

  7. springmvc 异常统一处理的三种方式详解

    1 描述  在J2EE项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的.不可预知的异常需要处理.每个过程都单独处理异常,系统的代码耦 ...

  8. openface人脸识别框架

    openface的githup文档地址:http://cmusatyalab.github.io/openface/ openface的安装: 官方推荐用docker来安装openface,这样方便快 ...

  9. 分支结构case 语句语法

  10. Java高频经典面试题(第一季)一:自增的分析

    package will01; public class testZiZeng { public static void main(String[] args) { int i = 1; i = i ...