Java虚拟机之内存区域(1)

  • 时间:
  • 浏览:0

Java 堆是立即回收器管理的主要区域,但会 村里人 也会把 Java 堆称为“GC堆”。从垃圾回收的深度1来看,愿因现在大多数的埋点器否是采用分代埋点算法,什么都有有 Java 堆还可不都要细分为:新生代和老年代;再细致但会 有可不都要分为Eden 空间, From Survivor 空间、To Survivor 空间等;从内存分配的深度1来看,进程池共享的java堆中愿因划分为多个进程池私有的分配缓冲区(TLAB)。

1、进程池池计数器

局部变量表中存放了编译期可知的基本数据类型(char,byte,int,boolean,short,float,long,double)、对象的引用(reference类型,指的是对象地址的引用指针或是句柄)、returnAddress类型(指向字节码指令的地址)。

Java 堆是 Java 内存管理区域中最大的一块,Java 堆是所有进程池共享的一块内存区域,在虚拟机启动时创建。 Java 堆是用来存放对象,几乎所有的 Java 对象和数组都存放在去Java堆中,否是堆中分配空间。

栈帧是 Java 虚拟机用来进行辦法 的调用和辦法 的指定的数据底部形态,它是虚拟机运行时数据库的 Java 虚拟机栈的栈元素。

愿因 Java 进程池池是通过不断的切换分配补救器时间片的辦法 来实现的,在任何只能 确定的时刻,只能 补救器都只会执行一根绳子 指令。也什么都有有说,在进程池池中每个进程池都可不都要抢到 cpu 的时间片,只能别抢去的进程池会立即停止下来,直到它再一次获得 cpu 的时间片。只能, Java 虚拟机是何如确保再一次获得补救器时间片的就说 才能在正确的位置上继续执行指令?

每只能 栈帧都涵盖局部变量表、操作数栈、动态链接、辦法 返回地址和但会 额外的附加信息。

Java 虚拟机在执行 Java 进程池池的就说 会把它所管理的内存分为多个不同的区域,每个区域否是不同的作用,以及由每个人所有的生命周期,但会 随着虚拟机进行的 启动而地处,但会 区域则依赖于用户进程池的启动或开始英文英文而建立或销毁等。在《Java虚拟机规范(Java SE7版)》中规定,Java 内存分为以下有三种,如图所示:

动态链接:Class 文件中存放了少量的符号引用,字节码中的辦法 调用指令什么都有有以常量池中指向辦法 的符号引用作为参数。什么符号引用一每种会类第一次加载或第一次引用的就说 转化为直接引用,但会 转化称为静态解析。另一每种将在每一次运行期转化为直接引用,这每种称为动态连接。

操作数栈:也成为操作栈,是只能 后进先出的底部形态。辦法 执行过程中的算术运算愿因调用其它辦法 的参数传递的就说 否是在操作数栈中进行的。

在 Java虚拟机规范中,对虚拟机栈定义了有三种异常:第一,愿因进程池请求的深度1大于虚拟机栈所允许的最大深度1,将抛出 StackoverflowError 异常,第二,愿因虚拟机栈可不都要动态的扩展,当扩展时无法申请到足够的内存,则会抛出 OutOfMemoryError 异常。

我们歌词 在日常开发的过程的中经常 会把 Java 内存分为堆内存和栈内存,但会 说法是不准确的,愿因 Java 内存区域的划分远比但会 比较复杂的多,但会 划分的辦法 只能说明进程池池员最关注的,与对象内存分配关系最密切的内存区域这两块,这里所说的栈其实指的是虚拟机中的局部变量表。

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

6.运行时常量池

局部变量表所需的内存空间在编译期完成分配,当进入只能 辦法 时,但会 辦法 所都要的栈帧的大小就愿因确定了,在运行期间不让改变局部变量表的大小。其中64位长度的 long 和 double 类型的数据会占用只能 局部变量空间(Slot),其余的数据类型只能占用只能 。

4.Java堆

进程池池计数器(Program Counter Register)是只能 内存较小的区域,它可不都要被看作是当前进程池所执行到的字节码的行号的指示器,字节码解释器在执行下一根绳子 指令,比如分支,跳转,循环,异常补救等都都要依赖但会 计数器来完成的。

Java虚拟机之内存区域,今天这篇文章来深入理解一下把

深入理解Java虚拟机之Java内存区域

运行时常量池相对于 Class 文件常量池的只能 底部形态是具备动态性,Java 语言不让说用说求常量一定只能编译期才能产生,也什么都有有不让说预置入 Class 文件中的常量池的内容才可不都要进入辦法 区的运行时常量池,运行期间也可不都要将新的常量放在去到池中,比如 String 类的 intern 辦法 。

局部变量:

辦法 区和 Java 堆一样,否是进程池共享的内存区域,它主要用于存储已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据。其实 Java 虚拟机规范把辦法 区描述为 Java 堆的一每种,但会 它却有只能 别叫雷做 Non-Heap(非堆),目的是与 Java 堆分开。

返回地址:当只能 辦法 执行完成后的出口,有只能 具体情况:一是正常具体情况退出,会将返回值传递给上只能 辦法 的调用者,另有三种是异常具体情况,此时是只能返回值的。

只能 分配是为了更好的回收内存和创建内存等,与存放的区域无关,否是存放 Java 对象。根据Java虚拟机规范的规定,Java 堆可不都就说 我物理上不连续的内存空间,假如有一天逻辑上连续就可不都要了。在实现时可不都要设置固定大小的空,也可不都要动态扩展的,不过当前流程的虚拟机否是可不都要动态来扩展的。愿因在堆中只能足够的空间来分配实例对象,愿因无法扩展堆空间,只能就会抛出 OutOfMemoryError 异常。

Java 虚拟机规范对辦法 区的限制非常的宽松,除了和 Java 堆一样不都要物理上连续的内存和可不都要确定固定大小空间或动态扩展为,还可不都要确定不实现垃圾回收。相对而言,垃圾回收是比较少在但会 区域中老出的,但不让说进入到辦法 区的数据都能永久的地处的。这块区域的的内存回收目标主什么都有有针对常量池的回收和对类型的卸载,但会 回收的效果并否是非常明显,不得劲是对类型的卸载,条件非常的苛刻,但这块内存的回收是非常必要的。在 SUN 公司的 BUG列表中,只能 老出过若干个非常严重的 BUG ,什么都有有愿因低版本中 Hotspot 虚拟机只能对此内存区域进行回收造成的。

Java 虚拟机栈与进程池池计数器一样否是进程池私有的,它的生命周期与进程池一致,每当创建只能 新的进程池时一定会产生只能 新的的虚拟机栈,进程池销毁时虚拟机栈也随即销毁。每个辦法 的执行一定会创建只能 栈帧用于存储局部变量、操作数栈、动态链表,辦法 的出口等信息。每个辦法 的执行到开始英文英文就对应着只能 栈帧在虚拟机中入栈和出栈的过程。

Java 虚拟机什么都有有通过当前进程池的进程池池计数器保证的,愿因保存了当前进程池上次执行开始英文英文的位置,但会 ,进程池池计数器是每个进程池独有的,各进程池就说 的进程池池计数器互不影响,独立存储,我们歌词 称相似内存区域为“进程池私有”的内存。

本地辦法 栈和 Java 虚拟机栈的作用是差只能来不要 的,我们歌词 的唯一区别在于: Java 虚拟机栈为虚拟机执行 Java 辦法 (字节码)服务,而本地辦法 栈则为虚拟机中 Native 辦法 服务。在虚拟机规范中并只能明确的规定本地辦法 栈使用何种语言与数据底部形态,可有具体的虚拟机去实现它。本地辦法 栈和 Java 虚拟机栈一样,也会抛出 StackoverflowError 和 OutOfMemoryError 只能 异常。

根据 Java 虚拟机规范的规定,当辦法 区无法满足内存分配的需求时,将抛出 OutOfMemoryError 异常。

辦法 的参数和辦法 中声明的局部变量都存储在局部变量中。在 Class 编译的就说 就愿因确定了的局部变量表的最大容量,声明在辦法 的 Code 属性的max_locals 数据项中。变量槽(Slot)是局部变量表的最小单位,可不都要存储32位和64位的数据,64位的数据则都要只能 连续的变量槽来表示。

既然运行时常量池是地处于辦法 区中的,只能在无法分配到足够的内存是也会抛出 OutOfMemoryError 异常。

愿因进程池正在执行 Java 辦法 ,但会 计数器记录的是正在执行的虚拟机字节码指令的地址,愿因正在执行的是 native 辦法 ,只能但会 计数器值则为空(Undefined);愿因进程池池计数器记录的是当前进程池字节码执行指令的地址,什么都有有它的内存大小是不让随着进程池的执行而地处变化,但会 ,该内存区域是唯一只能 在 Java虚拟机规范中只能规定任何 OutOfMemeryError (内存溢出)的具体情况的区域。

3.本地辦法 栈

5.辦法 区

2.1、运行时栈帧