butterfly,深化了解JVM(一)——JVM内存模型,眼睛肿

JVM内存模型

Java虚拟机(Java Virtual Machine=JVM)的内存空间分为五个部分,分别是:

1. 程序计数器

2. Java虚拟机栈

3. 本地办法栈

4. 堆

5. 办法区。



下面临这五个区域打开深化的介绍。

一、 程序计数器

1.1. 什么是程序计数器?

程序计数器是一块较小的内存空间,能够把它看作当时线程正在履行的字节码的行号指示器。也就是说,程序计数器里边记载的是当时线程正在履行的那一条字节码指令的地址。

注:可是,假如当时线程正在履行的是一个本地办法,那么此刻程序计数器为空。

1.2. 程序计数器的效果

程序计数器有两个效果:

字节码解说器经过改动程序计数器来顺次读取指令,然后完成代码的流程操控,如:次序履行、挑选、循环、反常处理。

在多线程的情况下,程序计数器用于记载当时线程履行的方位,然后当线程被切换回来的时分能够知道butterfly,深化了解JVM(一)——JVM内存模型,眼睛肿该杰克线程前次运转到哪儿了。

1.3. 程序计数器的特色

是一块较小的存储空间

线程私有。每条线程都有一个程序计数器。

是仅有一个不会呈现OutOfMemoryError的内存区域唇珠。

生命周期跟着线程的创立而创立,跟着线程的结束而逝世。

二. Java虚拟机栈(JVM Stack)

2.1. 什么是Java虚拟机栈?

Java虚拟机栈是描绘Java办法运转进程的内存模型。

Java虚拟机栈会为每一个行将运转的Java办法创立一块叫做“栈帧”的区域,这块区域用于存储该办法在运转进程中所需求的一些信息,这些信息包括:

局部变量表

寄存根本数据类型变量、引证类型的变量、returnAddress类型的变量。

操作数栈

动态链接

办法出口信息

当一个办法行将被运转时,Java虚拟机栈首要会在Java虚拟机栈中为该办法创立一块“栈帧”,栈帧中包括局部变量表、操作数栈、动态链接、办法出口信息等。当办法在运转进程中需求创立局部变量时,就将局部变量的值存入栈帧的局部变量表中。

当这个办法履行结束后,这个办法所对应的栈帧将会出栈,并开释内存空间。

留意:人们常说,Java的内存空间分为“栈”和“堆”,栈中寄存局部变量,堆中寄存方针。

这句话不完全正确!这儿的“堆”能够这么了解,但这儿的“栈”只代表了Java虚拟机栈中的局部变量表部分。真实的Java虚拟机栈是由一个个栈帧组成,而每个栈帧中都具有:局部变量表、操作数栈、动态链接、办法出口信息。

2.2. Java虚拟机栈的特色

局部变量表的创立是在办法被履行的时分,跟着栈帧的创立而创立。而且,局部变量表的巨细在编译时期就确认下来了,在创立的时分只需分配事前规定好的巨细即可。此外,在办法运转的进程中局部变量表的巨细是不会发作改动的。

Java虚拟机栈会呈现两种反常:StackOverFlowError和OutOfMemoryError。

a) StackOverF癌细胞lowError:

若Java虚拟机栈的内存巨细不答应动态扩展,那么当线程恳求栈的深度超越当时Java虚拟机栈的最大深度的时分,就抛出StackOverFlowErrobutterfly,深化了解JVM(一)——JVM内存模型,眼睛肿r反常。

b) OutO纤夫的爱fMemoryError:

若Java虚拟机栈的内存巨细答应动态扩展,且当线程恳求栈时内存用完了,无法再动态扩展了,此刻抛出OutOfMemoryError反常。

Java虚拟机栈也是线程私有的butterfly,深化了解JVM(一)——JVM内存模型,眼睛肿,每个线程都有各自的Java虚拟机栈,而且跟着线程的创立而创立,跟着线程的逝世而逝世。

注:StackOverFlowError和OutOfMemoryError的异同?

StackOverFlowError表明当时线程恳求的栈超越了事前定好的栈的最大深度,但内存空间或许还有许多。

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

3. 本地办法栈

3.1. 什么是本地办法栈?

本地办法栈和Java虚拟机栈完成的功用相似,只不过本地办法区是本地办法运转的内存模型。

本地办法被履行的时分,在本地办法栈也会创立一个栈帧,用于寄存该本地办法的局部变量表、操作数栈、动态链接、出口信息。

办法履行结束后相应的栈帧也会出栈并开释内存空间。

也会抛出StackOverFlowError和OutOfMemoryError反常。

4. 堆

4.英豪志1. 什么是堆?

堆是用来寄存方针的内存空间。

简直一切的方针都存储在堆中。

4.2. 堆的特色

线程同享 权利的游戏第一季

整个Java虚拟机只要一个堆,一切的线房贷核算器在线核算程都拜访同一个堆。而程序计数器、Java虚拟机栈、本地办法栈都是一个线程对应一个的。

在虚拟机发动时创立

废物收回的首要场所。

能够进一步细分为:新生代、老时代。

新生代又可被分为:Eden、From Survior、To Survior。

不同的区域寄存具有不同生命周期的方针。这样能够依据不同的区域运用不同的废物收回算法,然后更具有针对性,然后更高效。

堆的大butterfly,深化了解JVM(一)——JVM内存模型,眼睛肿小既能够固定也能够扩展,但干流的虚拟机堆的巨细是可扩展的,因而当线程恳求分配内存,但堆已满,且内存已满无法再扩展时,就抛出OutOfMemoryError。

5. 办法区

5.1. 什么是办法区?

Java虚拟机标准中界说办法区是堆的一个逻辑部分。

办法区中寄存现已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等。

5.2. 办法区的特色

线程同享

办法区是堆的一个逻辑部分,因而和堆相同,都是线程同享的。整个虚拟机中只要一个办法区。

永久代

办法区中的信息一般需求长期存在,而且它又是堆的逻辑分区,因而用堆的区分办法,咱们把办法区称为老时代。

内存收回功率低

办法区中的信息一般需求长期存在,收回一遍内存之后或许只要少数信息无效。

对办法区的内存收回的首要方针是:对常量池的收回 和 对类型的卸载。

Java虚拟机标准对办法区的要求比较宽松。

和堆相同,答应固定巨细,也答应可扩展的巨细,还答应不完成废物收回。

5.3. 什么是运转时常量池?

办法区中寄存三种数据:类信息、常量、静态变量、即时编译器编译后的代码。其间常量存储在运转时常量池中。

咱们一般在一个类中经过public static final来声明一个常量。这个类被编译后便生成Class文件,这个类的一切信息都存储在这个class文件中。

当这个类被Java虚拟机加载后,class文件中的常量就寄存在办法区的运转时常量池中。而且在运转期间,广州动物园能够向常量池中增加新的常量。如:String类的intern()云服务办法就能在运转期间向常量池中添胡思乱想加字符串常量。

当运转时常量池中的某butterfly,深化了解JVM(一)——JVM内存模型,眼睛肿些常量没有被方针引证,一起也没有被变量引证,那么就需求多伦多大学废物收集器收回教师招聘网。

6. 直接内存

直接内存是除Java虚拟机之外的内存,但也有或许被Java运用。

在NIO中引入了一种根据通道和缓冲的IO办法。它能够经过调用本地办法直接分配Jbutterfly,深化了解JVM(一)——JVM内存模型,眼睛肿ava虚拟机之外的内存,然后经过一个存储在Java堆中的DirectByteBuffer方针直接操作该内存,而无需先将外面内存中的数据复内痔的症状制到堆中再操作,然后提升了数据操作的功率。

直接内存的巨细不受Ja类组词va虚拟机操控,但既然是内存,当内存不足时就会抛出OOM反常。

综上所述

Java虚拟机的内存模型中总共有两个“栈”,分别是:Ja素颜va虚拟机栈和本地办法栈。

两个“栈”的功用相似,都是办法运转进程的内存模型。而且两个“栈”内部结构相同电脑桌面,都是线程私有。

只不过Java虚拟机栈描绘的是Java办法运转进程的内存模型,而本地办法栈是描绘Java本地办法运转进程butterfly,深化了解JVM(一)——JVM内存模型,眼睛肿的内存模型优创智合。

Java虚拟机的内存模型中总共jlpt有两个“堆”,一个是本来的堆,一个是办法区。办法区本质上是归于堆的一个重生追美记逻辑部分。堆中寄存方针,办法区中寄存类信息、常量、静态变量、即时编译器编译的代码。

堆是Java虚拟机中最大的一块内存区域,也是废物收集器首要的作业区域。

程序计数器、Java虚拟机栈、本地办法栈是线程私有的,即每个线程都具有各自的程序计数器、Java虚拟机栈、本地办法区。而且他们的生命周期和所属的线程相同。

而堆、办法区是线程同享的,在Java虚拟机中只要一个堆、一个办法栈。并在JVM发动的时分就创立,JVM中止才毁掉。

假如你也对Java高并发、分布式、高性能、spring等技能感兴趣能够重视我的微信大众号(Javasuiyue)或许查找Java后端进阶,每天8点整时一篇干货哦!