JVM内存模型小结

JVM运行时的数据区域划分图如下,该图是JVM内存模型最主要的内容。

从图中可以看出来,JVM将内存主要划分为五个部分:程序计数器、Java虚拟机栈、本地方法栈、Java堆和方法区。这些被划分为用途不一的数据区域有着各自的特点,它们都有自己创建和销毁的时间,有的区域随着进程的启动而存在,有的是伴随着用户线程的启动而建立、随着线程的结束而销毁。

(一) 程序计数器(Program Counter Register)

1> 内存空间较小;

2> 当前线程所执行的字节码行号指示器;

功能:a、在JVM中,字节码解释器的工作进行就是通过改变计数器的值来选取下一条需要执行的字节码指令

b、在3>中有解释,是作为线程切换回来继续执行的标记点

3> 线程私有;

线程私有:通俗来讲就是每一个线程在执行时都有一个独立的程序计数器,各个线程被独立存储。目的是为了记录所执行的线程进行到了哪一步。这样设计的原因主要是由多线程的实现方式所决定的,在Java虚拟机中,多线程的实现是通过线程轮流切换并分配处理器执行时间的方式,也就是在任何一个具体的时刻下,一个处理器只能够执行一个线程下的代码指令,这样在不断的线程切换过程中,同一个线程想要继续往下执行,就必须知道它上一次执行的位置,这个工作就是通过程序计数器完成的。

4> 计数器的值;

若线程正在执行的是Java方法:正在执行的虚拟机字节码指令的地址;

若线程正在执行的是Native方法:空值(Undefined);

Native方法(本地方法):为了补充Java语言无法直接访问系统底层的一种方法,由C或C++语言完成,实际上Native Method就是Java调用非Java代码的接口。

5> 计数器这块内存区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域。

6> 生命周期与线程相同。

(二)Java虚拟机栈(Java Stack)

1> 定义:描述Java方法执行的内存模型;

a、详细解释:每个方法执行时都会创建一个栈帧,在这个栈帧中存放着“局部变量表、操作数栈、动态链接、方法出口等”。

以我的理解就是这一块内存就是一个栈,栈帧是Java虚拟机栈的诸多元素,每一个栈帧都代表这一个方法正在被执行,其中存放着一些有关该方法中信息。

每一个方法从调用一直到执行结束,也就对应着一个栈帧在Java虚拟机栈中入栈出栈的过程。

b、局部变量表:

基本数据类型、(64位的long和double类型的数据会占用2个局部变量空间,其余占1个)

对象引用、(reference类型??,不同于对象本身,可能是一个指向对象起始地址的引用指针,也可能                                              是指向一个代表对象的句柄或其他与此对象相关的位置)

returnAddress类型 、(指向了一条字节码指令的地址)

局部变量表所需的内存空间在编译期间完成分配,所以在线程进行时调用了一个方法,为之创建的栈帧中局部变量空间是完全确定的,并且在方法执行过程中不会改变局部变量表的大小。

2> 线程私有;

线程私有: 也就是和计数器一样,每一个线程有独立的Java虚拟机栈,这个线程中的每个方法执行过程就会创建一个栈帧,方法执行的全过程就是栈帧在该线程对应的虚拟机栈中入栈和出栈的过程。

3> 生命周期与线程相同;

4> 该内存区域两种异常状况:

a、线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常;

b、若虚拟机支持动态扩展,如果扩展时无法申请到做够的内存,就会抛出OutOfMemoryError异常。

StackOverFlowError表示当前线程申请的栈超过了事先定好的栈的最大深度,但内存空间可能还有很多。

而OutOfMemoryError是指当线程申请栈时发现栈已经满了,而且内存也全都用光了。

5> 不能简单地将Java内存区简单分为堆和栈。

这样区分太过粗糙,只不过是将对象和局部变量区分开,简单地认为对象存放在堆中,局部变量存放在栈中。其实从上面的整理中也可以看出来,Java虚拟机栈实际上是由这些栈帧组成的,而每个栈帧中的内容并不只有局部变量表。

(三)本地方法栈

1> 定义:与Java虚拟机栈的定义很相似,可以说是Native方法执行的内存模型;

2> 虚拟机规范中对本地方法栈中方法使用的语言、使用方式与数据结构并没有强制规定。甚至有的虚拟机(Sun HotSpot)直接就把本地方法栈和虚拟机栈合二为一;

3> 抛出StackOverflowError和OutOfMemoryError异常的情况与Java虚拟机栈是一样的;

4> 其他特性参考Java虚拟机栈。

(四)Java堆

1> 系Java虚拟机所管理内存中最大的一块,虚拟机启动时创建;

2> 被所有线程共享;

所有地线程都可以访问不同地对象,从内存分配地角度来看,线程共享地Java堆中可能划分出多个线程私有地分配缓冲区(TLAB),不过无论如何划分,无论哪个区域,存放地都是对象实例,这样不同地线程将各自地对象实例放在了看似共享的Java堆的各自的缓冲区上,这样的好处是可以更好的回收内存,也可以更快分配内存。

3> 唯一目的就是存放对象实例,几乎所有实例对象都存在此处;

在Java虚拟机规范中描述为:所有的对象实例以及数组都要在这里分配内存。但是随着JIT编译器的发展与逃逸分析技术逐渐成熟,栈上分配、标量替换优化技术将会导致一些微妙的变化发生,所以这里会严谨地加上“几乎所有”而不是全部,至于什么是逃逸分析,栈上分配,标量替换,以后学习中应该会专门去了解学习一下吧。

4>可以处于物理上不连续的内存空间,但逻辑上需要连续;

5> 可以实现固定大小的,也可以是可扩展的。若在堆中没有内存完成实例分配,并且堆也无法再扩展时,将抛出OutOfMemoryError异常;

6> 又称“GC堆‘(Garbage Cpllected Heap)

内存回收用到的终极算法:分代收集算法,今后可以专门学习一下,该算法也是多个算法的整合。

(五) 方法区(Method Area)

1> 与Java堆类似,各线程共享的内存区域;

2> 存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等;

3> 规范中描述为堆的一个逻辑部分,习惯称为Non-Heap(非堆),目的是为了与Java堆区分;

4> 被称作“永久代”;

本质上两者并不一样,这样的叫法是因为HotSpot虚拟机的设计团队选择把GC分代收集扩展至方法区,或者说使用永久代来实现方法区而已,这样GC收集器就能像管理Java堆一样管理这部分内存,省去专门为方法区编写内存管理代码的工作。当然方法区也可以不进行GC收集。

5> 不需要连续的内存和可以选择固定大小或者可扩展外,也可以不实现GC收集;

该区域的内存回收目标主要是针对常量池的回收和对类型的卸载,但效果不好,条件苛刻,但是对于这部分的回收确实是有必要的。

6> 当方法区无法满足内存分配需求时,将抛出OutOfMemoryError异常

(六) 运行时常量池

1> 方法区的一部分;

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

2> 受到方法区内存的限制,当常量池无法再申请到内存时会抛出OutOfMemoryError异常;

(七) 直接内存

1> 不属于虚拟机运行时数据区的一部分,也不是规范中的定义;

2> JDK1.4加入了NIO类,一种基于通道与缓冲区的新I/O方式,NIO可以使用Native函数库直接分配堆外内存,然后通过一个存储在Java堆中的DirectByteBuffer对象作为直接内存的引用来操作直接内存,这样可以避免在Java堆和Native堆来回复制数据,从而提高性能;

3> 受总内存影响,也会出现OutOfMemoryError异常。

以上总结的就是JVM内存模型的相关概念和知识点,前五项以及那张内存模型图需要牢记,其中有些许疑问,不过也都是某些概念上的问题,具体关于每一块内存区域的定义作用,抛出的异常类型,已经理解。
————————————————
版权声明:本文为CSDN博主「Adelaide_Guo」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Adelaide_Guo/article/details/75394973

原文地址:https://www.cnblogs.com/yss818824/p/12267689.html

时间: 2024-11-13 09:21:26

JVM内存模型小结的相关文章

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

前提 JVM运行时数据区和JVM内存模型是两回事,JVM内存模型指的是JVM堆内存模型. 那JVM运行时数据区又是什么? 它包括:程序计数器.虚拟机栈.本地方法栈.方法区.堆. 来看看它们都是干嘛的 程序计数器:保存当前线程执行的指令的地址(大意如此). 虚拟机栈:由栈帧组成,而每个栈帧又包括局部变量表.操作数栈.动态连接(调用其他方法).出口(被调用时返回值) -- 每个栈帧就代表了一个方法的执行. 本地方法栈:类似虚拟机栈,只不过方法改成了native方法. 方法区:保存了类的各种信息.类的

JVM内存模型-转载

http://my.oschina.net/u/567296/blog/303780 JVM的内部结构如下图: JVM主要包括两个子系统和两个组件: 1. 两个子系统分别是Class loader子系统和Execution engine(执行引擎) 子系统: 1.1 Class loader子系统的作用:根据给定的全限定名类名(如 java.lang.Object)来装载class文件的内容到 Runtime data area中的method area(方法区域).Java程序员可以exten

jvm的stack和heap,JVM内存模型,垃圾回收策略,分代收集,增量收集(转)

深入Java虚拟机:JVM中的Stack和Heap(转自:http://www.cnblogs.com/laoyangHJ/archive/2011/08/17/gc-Stack.html) 在JVM中,内存分为两个部分,Stack(栈)和Heap(堆),这里,我们从JVM的内存管理原理的角度来认识Stack和Heap,并通过这些原理认清Java中静态方法和静态属性的问题. 一般,JVM的内存分为两部分:Stack和Heap. Stack(栈)是JVM的内存指令区.Stack管理很简单,push

JVM内存模型以及HotSpot的GC策略

概述 想要进一步掌握Java语言,必须要深入了解一下Java程序的运行环境.本文会对JVM的内存模型.Java内存自动管理机制.以及Oracle官方虚拟机HotSpot在GC方面的实现策略进行大概的梳理. 什么是Java的内存模型? 众所周知,Java程序是运行在JVM上面的,但是不具体指定是哪一款JVM,只要是符合一定的规范的JVM,都可以正确的运行Java字节码.该规范由Oracle官方提供,旨在描述一个抽象的JVM,它包含很多部分,包括class文件结构.运行时内存状态.指令集等. 而上述

jvm内存模型及分配

1.什么是jvm?(1)jvm是一种用于计算设备的规范,它是一个虚构出来的机器,是通过在实际的计算机上仿真模拟各种功能实现的.(2)jvm包含一套字节码指令集,一组寄存器,一个栈,一个垃圾回收堆和一个存储方法域.(3)JVM屏蔽了与具体操作系统平台相关的信息,使Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行.JVM在执行字节码时,实际上最终还是把字节码解释成具体平台上的机器指令执行. 2.jdk.jre.jvm是什么关系?(1)JRE(Java

JVM内存模型理解

Java虚拟机(Java VirtualMachine 简称JVM)是运行所有Java程序的抽象计算机,是Java语言的运行环境,它是Java 最具吸引力的特性之一. JVM内存模型 1.方法区和堆是所有线程共享的数据区 1)堆:存放对象的实例 2)方法区:存放已被虚拟机加载的类信息.常量.静态变量.即时编译器编译后的代码 3)运行时常量池:是方法区的一部分,存放Class的版本.字段.方法.接口等描述信息,字符串池就是这个!!! 2.程序计数器.虚拟机栈.本地方法栈是线程隔离的数据区 4)程序

JVM内存模型及垃圾回收机制

JVM内存模型1.栈Java栈是与每一个线程关联的,JVM在创建每一个线程的时候,会分配一定的栈空间给线程.存储局部变量.引用.方法.返回值等.StackOverflowError:如果在线程执行的过程中,栈空间不够用,那么JVM就会抛出此异常,这种情况一般是死递归造成的.2.堆 Java中堆是由所有的线程共享的一块内存区域,堆用来保存各种JAVA对象,比如数组,线程对象等. 2.1堆的分代JVM堆一般分为三个部分:Young:年轻代Young区被划分为三部分,Eden区和两个大小严格相同的Su

JVM内存模型及String对象内存分配

昨天看了一篇关于<Java后端程序员1年工作经验总结>的文章,其中有一段关于String和StringBuffer的描述,对于执行结果仍然把握不准,趁此机会也总结了下JVM内存模型. 1.JVM运行时数据区域 关于JVM内存模型之前也了解过一些,也是看过就忘,好记性比如烂笔头,记下来吧.参考此文章http://chenzhou123520.iteye.com/blog/1585224 图1 JVM运行时数据区域 (1).程序计数器(Program Counter Register): 程序计数

JVM内存模型,垃圾回收算法

JVM内存模型总体架构图 程序计数器多线程时,当线程数超过CPU数量或CPU内核数量,线程之间就要根据时间片轮询抢夺CPU时间资源.因此每个线程有要有一个独立的程序计数器,记录下一条要运行的指令.线程私有的内存区域.如果执行的是JAVA方法,计数器记录正在执行的java字节码地址,如果执行的是native方法,则计数器为空.虚拟机栈线程私有的,与线程在同一时间创建.管理JAVA方法执行的内存模型.每个方法执行时都会创建一个桢栈来存储方法的的变量表.操作数栈.动态链接方法.返回值.返回地址等信息.