运行时数据区示意图

1. 程序计数器

占用一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器。主要用来记录线程执行到哪条语句了,分支、循环、跳转、异常处理、线程恢复等功能都需要依赖这个计数器来完成。

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

2. Java 虚拟机栈

线程私有,生命周期与线程相同。虚拟机栈描述的是Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息。

局部变量表存放了编译期可知的各种基本数据类型、对象引用和returnAddress类型(指向了一条字节码指令的地址)。局部变量表所需的内存空间在编译期间完成分配,在方法运行期间不会改变局部变量表的大小。

在Java虚拟机规范中,对该区域规定了两种异常状况:1) 如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常。 2)如果虚拟机栈可以动态扩展,当扩展时无法申请到足够的内存,就会抛出OutOfMemoryError异常。

3. 本地方法栈

本地方法栈与虚拟机栈所发挥的作用非常相似,它们之间的区别不过是虚拟机栈为虚拟机执行Java方法服务,而本地方法栈则为虚拟机使用到的Native方法服务。

4. Java堆

Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。几乎所有的对象实例都在这里分配内存。

Java堆可分为:新生代和老年代。新生代又可细分为:Eden 区、From Survivor 区、To Survivor 区。

如果在堆中没有内存完成实例分配,并且堆也无法再扩展时,将会抛出OutOfMemoryError异常。

5. 方法区

方法区与Java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。有人也称方法区为“永久代”,但是本质上两者并不等价。某些虚拟机并不存在永久代的概念。

JDK1.8中,永久区被彻底移除,使用了新的元数据区存放类的元数据。默认情况下,元数据区只受系统可用内存的限制,但依然可以使用参数-XX:MaxMetaspaceSize指定永久区的最大可用值。

6. 运行时常量池

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

7. 直接内存

直接内存并不是虚拟机运行时数据区的一部分,也不是java虚拟机规范中定义的内存区域。但是这部分内存也被频繁地使用,而且也可能导致OutOfMemoryerror异常。

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

《深入理解Java虚拟机》笔记01 -- 运行时数据区的更多相关文章

  1. Java 虚拟机中的运行时数据区分析

    本文基于 JDK1.8 阐述分析 运行过程 我们都知道 Java 源文件通过编译器编译后,能产生相应的 .Class 文件,也就是字节码文件.而字节码文件通过 Java 虚拟机中的解释器,编译成特定机 ...

  2. 深入理解Java虚拟机一:运行时数据区域

    根据<Java虚拟机规范(第2版)>的规定,Java虚拟机管理的内存包括下图几个运行时数据区域: 1.程序计数器        程序计数器(Program Counter Register ...

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

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

  4. 介绍下Java内存区域(运行时数据区)

    介绍下Java内存区域(运行时数据区) Java 虚拟机在执行 Java 程序的过程中会把它管理的内存划分成若干个不同的数据区域.JDK 1.8 和之前的版本略有不同. 下图是 JDK 1.8 对JV ...

  5. Java虚拟机一:运行时数据区域

    java虚拟机在执行java程序的过程中,会把内存划分为若干个不同的数据区域.每个区域都有各自的用途,创建和销毁时间,按照<java虚拟机规范(Java SE 7 版)>的规定,虚拟机运行 ...

  6. 虚拟机系列 | JVM运行时数据区

    本文源码:GitHub·点这里 || GitEE·点这里 一.内存与线程 1.内存结构 内存是计算机的重要部件之一,它是外存与CPU进行沟通的桥梁,计算机中所有程序的运行都在内存中进行,内存性能的强弱 ...

  7. 学习笔记-jvm运行时数据区

    按照线程私有和共享区域来划分 线程私有 程序计数器 指向当前线程正在执行的字节码行号地址,如果是本地方法,值为undefined 虚拟机中唯一不会oom的区域 为什么会有程序计数器 - java天生多 ...

  8. 你必须了解的java内存管理机制(一)-运行时数据区

    前言 本打算花一篇文章来聊聊JVM内存管理机制,结果发现越扯越多,于是分了四遍文章(文章讲解JVM以Hotspot虚拟机为例,jdk版本为1.8),本文为其中第一篇.from 你必须了解的java内存 ...

  9. jvm入门及理解(三)——运行时数据区(程序计数器+本地方法栈)

    一.内存与线程 内存: 内存是非常重要的系统资源,是硬盘和cpu的中间仓库及桥梁,承载着操作系统和应用程序的实时运行.JVM内存布局规定了JAVA在运行过程中内存申请.分配.管理的策略,保证了JVM的 ...

随机推荐

  1. Java for LeetCode 125 Valid Palindrome

    Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignori ...

  2. java多线程---基础

    一, java多线程----线程与进程 进程: 程序(任务)的执行过程,拥有资源(共享内存,共享资源)和线程(一个或者多个,至少一个).  例如:打开任务管理器,qq,chrome,都属于进程. 线程 ...

  3. nodejs 基础篇整合

    nodeJs 基础篇整合 最近有朋友也想学习nodeJs相关方面的知识,如果你是后端想接近前端,node作为一门跑在服务端的JS语言从这里入门再好不过了.如果你正好喜欢前端,想走的更高,走的更远.no ...

  4. JMS消息可靠机制

    ActiveMQ消息签收机制: 客戶端成功接收一条消息的标志是一条消息被签收,成功应答. 消息的签收情形分两种: 1.带事务的session 如果session带有事务,并且事务成功提交,则消息被自动 ...

  5. JAVA- continue与break与return关键字

    continue与break关键字 for(int i=0;i<10;i++){ if(i%2==0){ continue; //跳过当前循环执行下一次循环 } System.out.print ...

  6. html5--1.3 元素的概念与3个常用标签

    html5--1.3 元素的概念与3个常用标签 学习要点 1.元素的概念 2.3个常用的标签 HTML 元素指的是从开始标签到结束标签的所有代码. 开始标签 元素内容 结束标签 <h1> ...

  7. 搭建LoadRunner中的场景(四)控制器的全局设置

    选择“Tools”菜单-“Options”选项打开设置窗口 1.超时设置 2.运行时设置 3.运行时文件存储设置 4.路径翻译表 路径翻译表是一种映射,将控制器上的文件路径转换为远程主机上的文件路径. ...

  8. JQuery调用iframe子页面函数/对象的方法

    父页面有个ID为mainfrm的iframe,iframe连接b.html,该页面有个函数test 在父页面调用b.html的test方法为: $("#mainfrm")[0].c ...

  9. openfire性能测试

    使用TSung对Jabber服务器openfire进行压力测试 http://blog.csdn.net/spider_zhcl/article/details/6073920 Tsung负载测试Ti ...

  10. 如何配置OpenFire上JVM的内存(Memory)

    目前OpenFire在Linux下有2种安装方式, 网上对于第二种Linux安装方式下如何配置JVM内存(Memory)并没有描述: tar -xzvf openfire_3_0_0.tar.gzmv ...