3.JVM内存区域划分

前言

上一节我们详细学习了类加载器,我们接着思考下一个问题:

  1.  类加载器将class文件加载到JVM内存的什么位置?
  2. JVM内部内存是怎样划分的?

通过本节我们将寻找到答案,并将掌握以下知识:

1. JVM虚拟机3大组成部分

2. 内存模型

3. 栈、堆详细解释

 干货满满,我坚持写,你加油看!!!

JVM虚拟机的内存划分

JVM虚拟机由3大部分组成:类装载子系统、运行时数据区(内存模型)、字节码执行引擎。这3部分是怎样配合工作的呢?

  •  类装载子系统将class文件加载到运行时数据区。
  • 字节码执行引擎去执行代码

我们主要研究的是运行时数据区,也叫做内存模型。内存模型内又主要划分成了5块内存区域:栈、堆、本地方法栈、方法区(元空间)、程序计数器。下面我们详细研究这5块内存区域。

3.JVM内存区域划分_第1张图片

 栈

   栈,又称为线程栈。在一个线程创建时,就会在栈空间内分配一块本线程私有的内存空间,叫做线程栈。每个线程的线程栈相互隔离,互不干扰。

   在线程执行某个方法时,会在自己的线程栈内给这个方法分配一块内存,叫做栈帧。主要用来存放局部变量。方法执行完毕之后,就会释放栈帧的内存。

   栈帧内部又主要划分成4块内存区域:局部变量表、操作数栈、动态链接、方法出口。

  • 局部变量表: 存放这个方法内的局部变量。  
  • 操作数栈:在运行期间,需要操作的操作数临时中转内存空间。
  • 动态连接:将符号引用转换为直接引用。
  • 方法出口:方法调用完成,去哪里继续执行。

3.JVM内存区域划分_第2张图片

方法区

 方法区,主要存放3类信息:常量、静态变量、类信息。

方法区和永久代以及元空间有什么关系?

 方法区、永久代以及元空间的关系类似于Java种的接口和类的关系。类可以看作是永久代和元空间,接口可以看作是方法区。也可以说永久代以及元空间是hotSpot虚拟机对虚拟机规范中方法区的两种实现。

永久代是1.8之前的方法区实现,元空间是1.8之后的元空间实现。

为什么要将永久代替换为元空间呢?

整个永久代有一个JVM本身设置的固定大小上限,无法进行调整。而元空间使用的是直接内存,受本机可用内存的限制,虽然元空间仍然可能溢出,但相对永久代几率更低。 

 3.JVM内存区域划分_第3张图片

程序计数器

程序计数器,是用来记录程序当前执行的位置。每个线程都有自己独有的程序计数器。

当User.class文件被加载到方法区后,由字节码执行引擎去执行代码,每执行完一句代码,字节码执行引擎都要去修改程序计数器中的代码位置。

3.JVM内存区域划分_第4张图片

 本地方法栈

C++语言编写的,native方法。每个线程独有的。

堆内存空间划分

堆内存分为年轻代和老年代,年轻代占堆内存的1/3,老年代占堆内存的2/3。年轻代内存又分为Eden区和Survivor区,Eden区占年轻代的8/10,Survivor区占年轻代的2/10。Survivor区又分为S0、S1,各占Survivor的一半空间。

3.JVM内存区域划分_第5张图片

为什么区分年轻代和老年代?

这主要和垃圾收集有关。我们创建的对象,它们的存活时间是不同的,为了方便收集垃圾对象,将堆内存划分为年轻代和老年代。

年轻代里的对象,创建之后很快就会被回收,需要一种垃圾回收算法。

老年代里的对象,需要长期存在,所以需要另外一种回收算法。所以需要两个区域来存放不同的对象。

3.JVM内存区域划分_第6张图片

 对象在年轻代和老年代间的流转

我们应该从以下几个问题入手,去分析对象在年轻代和老年代间的流转。

1. 哪些对象进入年轻代?哪些对象进入老年代?

2. 年轻代什么时候触发Minor GC?

3. 老年代什么时候触发Full GC?

1.哪些对象进入年轻代?哪些对象进入老年代?

  • 我们创建的大部分对象都会优先在年轻代分配内存,大对象会直接进入老年代。
  • 达到分代年龄的对象,从年轻代转移到老年代。

2.年轻代什么时候会触发Minor GC?

  • 当Eden区沾满后,就会触发Minor GC.

你可能感兴趣的:(JVM,jvm,java)