JVM内存数据模型

图片来自pixabay.com的Gipfelsturm69-2191891会员

本文将对JVM内存数据模型进行介绍,并给出一个简单的Java应用程序,描述其内存分配过程。在编写代码中,只有对类、各个变量和Java对象做到心中有数,才能“下笔”(敲代码)如有神。

1. JVM内存数据模型

如下图所示,

JVM内存数据模型

根据JVM规范,在运行时刻JVM内存数据分为如下6种,

  1. PC Register 程序计数器: 一个JVM中支持多个线程的执行,每个线程拥有各自独立的程序计数器,程序计数器指向线程执行的当前方法地址。
  2. JVM Stacks 栈区:每个线程拥有各自独立的JVM栈,一个栈存储着frames列表,每个frame对应着一个方法调用,其保存着方法调用所使用的本地变量和Java对象的引用,方法返回的值和异常。Frame按照后入先出的原则,执行并返回调用结果。这个数据区会发生如下两种内存溢出错误,
    • StackOverflowError 栈超过允许的调用深度
    • OutofMemoryError 栈超过允许的可用内存大小
  3. Heap 堆区,这个区的数据被所有线程所共享,是类对象创建时分配内存的地方。这个区的内存被JVM管理,实现对象的自动回收,也就是GC。这个数据区发生如下的内存溢出错误,
    • OutofMemoryError创建的对象超过可分配的内存大小
  4. Method Area方法区:这个区的数据被所有线程所共享,里面加载着类的定义,包括常量池,变量和方法数据等。这个数据区发生如下的内存溢出错误,
    • OutofMemoryError加载的类超过可分配的内存大小
  5. Run-Time Contant Pool 常量池,一个类文件中所定义的常量,一般会存储在方法区中。
  6. Native Method Stacks原生方法栈,Java内核代码中含有很多对操作系统原生方法的调用,这里存储着对原生方法调用的信息。其只对Java内核代码有意义,对于Java程序员来说,可以忽略这个区。