JVM内存区域简介(堆栈等)

Java Virtual Machine,即Java虚拟机,缩写JVM,是Java软件运行的平台。
JVM不直接作用于硬件,而是借助操作系统,通过操作系统来作用于硬件。

JVM ↔ 操作系统 ↔ 硬件

在JVM里有也有。堆是用来存放数据的,是多线程所共享的。栈是代码运行的内容,我们所写的方法,就会在栈里运行。

程序计数器

在讲解硬件CPU的工作原理时,也会出现程序计数器(PC),在CPU中,程序计数器用来存放下一步所执行的指令的地址。

在JVM中,程序计数器扮演类似的角色。程序计数器也是用来存放当前线程下一步执行的字节码指令等信息。每个线程都有独立的程序计数器,这样CPU才能在轮转切换下顺利地回到正确的执行位置。

为了各个线程之间相互不影响,因此JVM将此内存区域设计为线程私有的

虚拟机栈

JVM的栈也是线程私有的。站用来存储局部变量、操作栈、动态链接、方法出口等信息,它们存在一个名为“栈帧”的数据结构里。

栈的生命周期与线程相同。一个线程在创建时,JVM会为其创建一个专门的栈。线程运行完,栈的生命周期也就结束了,栈所占据的内存空间也会被释放,所以栈无所谓垃圾回收的问题。

补充:

8种基本类型的变量+对象的引用变量+实例方法都是在栈里面分配内存

本地方法栈

用C/C++写的部分,一般是native的方法才涉及。和虚拟机栈一样,这个也是线程私有的。

虚拟机堆

堆是放数据用的,一般来说是JVM中最大的内存区域,如同植物细胞液之于植物细胞。Java在运行期间创建的对象基本上都会放在堆里。
堆会产生垃圾,故而是垃圾回收的重点区域。

堆还可以进一步分类。堆包括“老生代”和“新生代”,其中新生代又包括“Eden区”和“Survivor区”。

新创建的对象会放在Eden区,这里就像产房一样。但是产房容易放满,把确认存活的婴儿送到普通病房。普通病房有两间,分别是 Survivor 0 和 Survivor 1 病房。总是会有一个病房先空着不住人,然后往另一间住婴儿,直到住满为止。如果住满了,就把还存活地移动到另一间病房,这个时候这一间又空了。

连续15次都存活的婴儿,就会被推入老生区了。老生区都是长期存在的对象。

方法区

方法区同样也是被多个线程共享的区域,存放已经被JVM加载的类信息、常量、静态变量、即时编译器等。
方法区的实现取决于JVM,有使用持久区的,也有使用元空间(Meta Space)的。Java 1.8及之后的版本都是使用元空间

小结

JVM的内存一般分为五个区域。

区域 线程拥有 作用 大小
程序计数器 线程私有 记录下一条指令的地址 很小
虚拟机栈 线程私有 存放方法的调用 一般
本地方法栈 线程私有 C/C++写的native方法 一般
虚拟机堆 共享 创建的对象等数据
方法区 共享 常量、静态变量等 一般

注意:

  • 程序计数器很小,不会溢出内存(Out Of Memory)。
  • 虚拟机是垃圾回收的重点照顾区域。
  • 诸如int等8种基本变量不在堆里,而是在栈里;而常量、静态变量也不在堆里,在方法区。
image.png

插图引自 Java运行时数据区域

你可能感兴趣的:(JVM内存区域简介(堆栈等))