笔记:Java虚拟机运行时数据区
Java虚拟机在执行Java程序的过程中会把它管的内存划分为以下若干个不同的区域:
1、程序计数器
程序计数器是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器;由于Java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现,在任何一个确定的时刻,一个处理器(对于多核处理器来说是一个内核)都只能执行一个线程中的指令,因此为了线程切换后能恢复到正确的执行位置,每条线程都需要一个独立的程序计数器来记录线程之前执行到哪里了。
如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令地址;如果正在执行的是一个Native方法,这个计数器值则为空(Undefined)。
这个内存区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域。
是线程私有的内存空间。
2、Java虚拟机栈
是线程私有内存空间。
虚拟机栈描述的是Java方法执行的内存模型:每个方法在执行的时候都会创建一个栈帧,用于存储局部变量表、操作数栈、动态链表、方法的出口信息等。每一个方法从调用直到执行完成的过程,就对应这一个栈帧在虚拟机栈中的入栈和出栈。
局部变量表存放了编译期可知的各种基本数据类型(boolean、byte、char、short、int、float、long、double)、对象引用(reference类型)和returnAddress类型(指向了一条字节码指令的地址)。其中64位的long和double类型占用两个局部变量空间,其余数据类型占用1个变量空间。
局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在帧中分配多大的局部变量空间是完全确定的,在方法运行期间是不会改变局部变量表大小的。
在Java虚拟机规范中,这个区域规定了两种异常情况:一、如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常;二、如果虚拟机可动态扩展(当前大部分虚拟机都可以动态扩展),如果扩展时无法申请到足够的内存,就会抛出OutOfMemoryError异常。
3、本地方法栈
本地方法栈和Java虚拟机栈发挥的作用非常相似,Java虚拟机栈是为虚拟机执行Java方法服务的,而本地方法栈是为虚拟机使用Native方法服务的。在虚拟机规范中对本地方法栈使用的语言、使用方式和数据结构没有强制规定,因此具体的虚拟机可以自由实现。
在HotSpot虚拟机中把虚拟机栈和本地方法栈合二为一。
是线程私有内存空间。
4、Java堆
Java堆是被所有线程共享的一块内存区域,是Java虚拟机所管理的内存中最大的一块。在虚拟机启动的时候创建。
Java程序创建的对象实例几乎都在这里分配内存;在Java虚拟机规范中描述:所有的对象实例以及数据都要在堆上分配,但是随着JIT编译器的发展和逃逸分析技术逐渐成熟,栈上分配、标量替换优化技术将会导致一些微妙的变化发生,所有对象分配都在堆上也渐渐变得不是那么“绝对”了。
Java堆是垃圾收集器管理的主要区域。
Java堆空间还可以分为:新生代和老年代,新生代又可以细分为:Eden空间、From Survivor空间和To Survivor空间。
如果在堆上没有内存空间可以完成对象实例分配,并且堆也无法再扩展时,将会抛出OutOfMemoryOut异常。
5、方法区
方法区也是各个线程共享的内存区域。
方法区用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
在HotSpot虚拟机上,GC分代收集扩展到了方法区,或者说使用永久代来实现方法区,这样可以像管理Java堆内存一样管理方法区内存,一般GC和老年代GC一起触发,所以在HotSpot虚拟机中,方法区也被称为“永久代”。
方法区的内存回收主要是针对常量池的回收和对类型的卸载(不过条件相当苛刻)。
方法区无法满足内存分配需求时,将抛出OutOfMemoryError异常。
6、运行时常量池
运行时常量池是方法区的一部分。
Class文件中除了有类的版本、字段、方法、接口等描述信息外,还有一项信息常量池,用于存放编译器生成的的各种字面常量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池中存放。
运行时常量池相对于Class文件常量池的另外一个重要特性是具备动态性,Java语言并不要求常量一定只有编译器才产生,运行期间也可能将新的常量放入到常量池中。
当常量池无法申请到内存时将会抛出OutOfMemoryError异常。
7、直接内存
直接内存并不是虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域。但是这部分内存也会被平凡的用到,也会出现OutOfMemoryError异常。
JDK1.4引入了NIO类,一种基于通道(channel)与缓冲区(Buffer)的I/O方式,它可以使用Native函数库直接分配堆外内存,然后通过一个存储在Java堆中的DirectButeBuffer对象作为这块内存的引用进行操作。这种方式避免了Java堆和Native堆中来回复制数据,在一些场景中可以显著提高性能。
笔记:Java虚拟机运行时数据区的更多相关文章
- 面试常问的 Java 虚拟机运行时数据区
写在前面 本文描述的有关于 JVM 的运行时数据区是基于 HotSpot 虚拟机. 概述 JVM 在执行 Java 程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,以 ...
- 《深入理解Java虚拟机》(二)Java虚拟机运行时数据区
Java虚拟机运行时数据区 详解 2.1 概述 本文参考的是周志明的 <深入理解Java虚拟机>第二章 ,为了整理思路,简单记录一下,方便后期查阅. 2.2 运行时数据区域 Java虚拟机 ...
- Java虚拟机运行时数据区
运行时数据区程序计数器Java虚拟机栈本地方法栈Java堆(GC堆)方法区运行时常量池 运行时数据区 Java虚拟机在运行Java程序时,会将它所管理的内存划分为若干个内存区域.这些数据区域有各自的用 ...
- Java 虚拟机运行时数据区
写在前面 本文描述的有关于 JVM 的运行时数据区是基于 HotSpot 虚拟机. 概述 JVM 在执行 Java 程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,以 ...
- 【深入理解Java虚拟机】Java虚拟机运行时数据区
Java虚拟机运行时数据区 线程私有 程序计数器 1.当前线程所执行的字节码的行号指示器. 2.唯一不会发生OutOfMemoryError的区域 3.如果执行的是java方法,计数器值为虚拟机字节码 ...
- 【JVM从小白学成大佬】2.Java虚拟机运行时数据区
目录 1.运行时数据区介绍 2.堆(Heap) 是否可能有两个对象共用一段内存的事故? 3.方法区(Method Area) 4.程序计数器(Program Counter Register) 5.虚 ...
- 【JVM学习】2.Java虚拟机运行时数据区
来源: 公众号: 猿人谷 这里我们先说句题外话,相信大家在面试中经常被问到介绍Java内存模型,我在面试别人时也会经常问这个问题.但是,往往都会令我比较尴尬,我还话音未落,面试者就会"背诵& ...
- Java 虚拟机运行时数据区详解
本文摘自深入理解 Java 虚拟机第三版 概述 Java 虚拟机在执行 Java 程序的过程中会把它所管理的内存划分为若干个不同的数据区域,这些区域有各自的用途,以及创建和销毁的时间,有的区域随着虚拟 ...
- 深入理解Java虚拟机&运行时数据区
其中,程序计数器.虚拟机栈.本地方法栈3个区域随线程而生,随线程而灭.
随机推荐
- java算法之超级丑数
问题描述: 写一个程序来找第 n 个超级丑数. 超级丑数的定义是正整数并且所有的质数因子都在所给定的一个大小为 k 的质数集合内. 比如给你 4 个质数的集合 [2, 7, 13, 19], 那么 [ ...
- 深入理解.net - 4.你必须知道的String
为什么要单独写string,主要是它太常用了,同时又太特殊了,特殊到CLR对它的处理都和其它对象不一样.简直可以称为VIP用户啊.本文并不是一篇介绍如何使用string的文章,而是旨在阐述string ...
- Oracle聚合函数
max(),min(),avg(),sum() 其中 avg(),sum()只能操作数字 , max(),min()能操作数字.日期.字母 等.
- linux设备驱动之字符设备驱动模型(2)
在上一篇中我们已经了解了字符设备驱动的原理,也了解了应用层调用内核函数的机制,但是我们每次操作设备,都必须首先通过mknod命令创建一个设备文件名,比如说我们要打开u盘,硬盘等这些设备,难道我们还要自 ...
- C++关于Union使用的部分总结
说明:未加说明,struct均指C++语言中的struct(可以有成员函数,可以定义访问属性) 1 什么是Union? (1)与class,struct相似用于定义数据结构:union 可以说是一种特 ...
- tkinter中checkbutton多选框控件和variable用法(六)
checkbutton控件 简单的实现多选: import tkinter wuya = tkinter.Tk() wuya.title("wuya") wuya.geometry ...
- python中用locust做简单的压力测试
验证导入包成功 首先导入locust模块,百度一下导入方法很多,就不多说了 验证导入成功或失败,在终端中(windows中是cmd)输入:locust --help 导入成功后会出现如下界面: 编辑运 ...
- 2013-09-16 构建C1000K的服务器(1) – 基础
http://www.ideawu.net/blog/archives/740.html 著名的 C10K 问题提出的时候, 正是 2001 年, 到如今 12 年后的 2013 年, C10K 已经 ...
- BITE
<Google软件测试之道> 读后感言: p147 提到的BITE实在是太让人心动了, 一个简单的动作即可提交一个信息齐全的bug,连非专业测试人员也能轻松做到.身边很多人也都碰到过提交b ...
- BZOJ_3238_[Ahoi2013]差异_后缀数组+单调栈
BZOJ_3238_[Ahoi2013]差异_后缀数组+单调栈 Description Input 一行,一个字符串S Output 一行,一个整数,表示所求值 Sample Input cacao ...