深入浅出Java语言的JVM内存结构
2023-11-09 11:50:17
一、JVM内存结构概述
在Java的世界中,一切都是对象。无论是基本类型还是复杂类型,都被看作是对象。在Java应用程序运行期间,JVM会为每个对象分配内存空间,这些内存空间可以分为以下5个部分:
- 堆(Heap) :堆是Java应用程序中最大的内存区域,用于存储所有对象实例以及数组。堆的大小可以通过
-Xmx
和-Xms
参数进行设置,默认情况下,堆的大小是物理内存的1/4。 - 栈(Stack) :栈是Java应用程序中用于存储局部变量和操作数的内存区域。栈的大小可以通过
-Xss
参数进行设置,默认情况下,栈的大小是1MB。 - 方法区(Method Area) :方法区是Java应用程序中用于存储已被加载的类信息、常量和静态变量的内存区域。方法区的大小可以通过
-XX:MaxPermSize
参数进行设置,默认情况下,方法区的大小是物理内存的1/4。 - 本地方法栈(Native Method Stack) :本地方法栈是Java应用程序中用于存储本地方法的内存区域。本地方法栈的大小可以通过
-Xss
参数进行设置,默认情况下,本地方法栈的大小是1MB。 - 程序计数器(Program Counter Register) :程序计数器是Java应用程序中用于存储当前正在执行的指令地址的内存区域。程序计数器的大小通常是4字节,但是具体大小取决于JVM的实现。
二、堆(Heap)
堆是Java应用程序中最大的内存区域,用于存储所有对象实例以及数组。堆的大小可以通过-Xmx
和-Xms
参数进行设置,默认情况下,堆的大小是物理内存的1/4。
堆内存被分为年轻代和老年代,年轻代又分为Eden空间、Survivor空间0和Survivor空间1。对象在被创建后首先被分配到Eden空间,当Eden空间满时,会触发一次Minor GC,将Eden空间和Survivor空间0中存活的对象复制到Survivor空间1中,然后清空Eden空间和Survivor空间0。当Survivor空间1满时,会触发一次Major GC,将Survivor空间1中存活的对象复制到老年代中,然后清空Survivor空间1。
三、栈(Stack)
栈是Java应用程序中用于存储局部变量和操作数的内存区域。栈的大小可以通过-Xss
参数进行设置,默认情况下,栈的大小是1MB。
栈内存是线程私有的,每个线程都有自己的栈内存。栈内存是先入后出的,即后进先出(LIFO)的。当一个方法被调用时,会创建一个新的栈帧,用于存储该方法的局部变量和操作数。当方法执行完毕后,栈帧会被销毁。
四、方法区(Method Area)
方法区是Java应用程序中用于存储已被加载的类信息、常量和静态变量的内存区域。方法区的大小可以通过-XX:MaxPermSize
参数进行设置,默认情况下,方法区的大小是物理内存的1/4。
方法区是共享的,所有线程都共享同一个方法区。方法区在JVM启动时被创建,并在JVM关闭时被销毁。
五、本地方法栈(Native Method Stack)
本地方法栈是Java应用程序中用于存储本地方法的内存区域。本地方法栈的大小可以通过-Xss
参数进行设置,默认情况下,本地方法栈的大小是1MB。
本地方法栈是线程私有的,每个线程都有自己的本地方法栈。本地方法栈是先入后出的,即后进先出(LIFO)的。当一个本地方法被调用时,会创建一个新的本地方法栈帧,用于存储该本地方法的局部变量和操作数。当本地方法执行完毕后,本地方法栈帧会被销毁。
六、程序计数器(Program Counter Register)
程序计数器是Java应用程序中用于存储当前正在执行的指令地址的内存区域。程序计数器的大小通常是4字节,但是具体大小取决于JVM的实现。
程序计数器是线程私有的,每个线程都有自己的程序计数器。程序计数器在JVM启动时被创建,并在JVM关闭时被销毁。
七、总结
Java虚拟机(JVM)的内存结构包括堆、栈、方法区、本地方法栈和程序计数器5个部分。其中,堆是用于存储所有对象实例以及数组的内存区域;栈是用于存储局部变量和操作数的内存区域;方法区是用于存储已被加载的类信息、常量和静态变量的内存区域;本地方法栈是用于存储本地方法的内存区域;程序计数器是用于存储当前正在执行的指令地址的内存区域。