云服务器

Java JVM 运行时内存区域介绍

2017-06-22 10:40:24 0

理解JVM运行时的内存结构,有助于我们java程序开发。在Java中,有一个常见的致命错误OutOfMemoryError,它就是与JVM的内存区域相关的。熟悉JVM内部的工作原理,能让我们更好的规避这些错误。本文将介绍JVM内存区域的类型,以及他们是如何工作的。

JVM运行时内存区域类型:

  • 程序计数器PC (Program Counter Register)
  • 虚拟机栈 (Java Virtual Machine Stacks)
  • 堆区域 (Heap Memory)
  • 方法区 (Method Area)
  • 运行时常量池 (Run-time Constant Pool)
  • 本地方法栈 (Native Method Stacks)

这六个内存区域,可以划分为一下两类:

  • 线程独立的(绿色部分), 这些内存区域是独立分配给单个线程的,在线程开始的时候创建,在线程结束的时候销毁。
  • 线程共享的(紫色部分),这些内存区域是公用的,能被各个线程访问到,它们在JVM启动的时候创建,在JVM停止时销毁。
这六个内存区域,可以划分为一下两类:
  • 线程独立的(绿色部分), 这些内存区域是独立分配给单个线程的,在线程开始的时候创建,在线程结束的时候销毁。
  • 线程共享的(紫色部分),这些内存区域是公用的,能被各个线程访问到,它们在JVM启动的时候创建,在JVM停止时销毁。
 
  1. 程序计数器
在一般的计算机结构中,程序计数器用于保存当前执行的指令的位置。就像一个指针,指向程序中一系列操作指令。在JVM中,也是相同道理。Java支持多线程体系结构,每当一个新线程创建时,程序计数器也会相应创建。它指向所在线程当前正在执行的语句。如果当前执行的方法是本地方法,那么程序计数器的值将是未知。
  1. 虚拟机栈
虚拟机栈是用来存储JVM帧的。JVM不会直接操纵这些栈,这些栈只是帧的存储单元。栈的内存分为固定部分和动态部分。动态部分会根据需要动态扩展。JVM帧在一个方法被调用时创建,他提供动态链接。线程负责创建和管理JVM栈。

StackOverflowError, 栈溢出错误。在固定大小的JVM栈中,程序运行时,当栈空间不足的时候,就会报这个错误。

OutOfMemoryError, 内存溢出错误。在动态大小的JVM栈中,当程序需要扩展空间获得更多内存时,但外部没有更多可用内存空间时,就会报这个错误。

  1. 堆内存
堆内存用于存储各种对象和数组。堆内存是被各个线程共享的。这部分区域就是需要用到Java垃圾收集(GC)机制的地方了。当JVM启动时,堆区域就会被创建。当其中的某些区域被GC时,相应区域就会被回收。程序运行时,堆空间不足也会抛出OutOfMemoryError。
  1. 方法区
一般来说,方法区逻辑上是堆区域的一部分,但是这取决于JVM的实现。方法区保存了被加载的类的结构和属性,以及所有静态属性数据和结构。它也包含方法数据,方法和构造器代码,运行时常量池。方法区在JVM启动时被创建,并被所有线程共享。当已分配的方法区大小不足时,也会抛出OutOfMemoryError。
  1. 运行时常量池
运行时常量池在方法区中的一个区域(jdk7以后已经移到堆中)。当一个类或接口被创建时,运行时常量池会被JVM创建。运行时常量池保存着一张常量表,可以让每个类和接口使用。常量表保存着各个常量的字面量。当JVM无法分配足够空间给运行时常量池时,也会抛出OutOfMemoryError。
  1. 本地方法栈
支持本地方法调用的JVM,会有一个本地方法栈。它由每个线程创建,供本地方法使用。如果本地方法没有被JVM加载,则不需要创建本地方法栈。本地方法栈的内存大小管理类似普通的JVM栈,也有固定和动态两种类型。JVM当空间不足的时候,同普通栈的情况,会相应抛出StackOverflowError或OutOfMemoryError。

本文主要介绍了Java运行时的内存区域,以及对应的一些错误原因。了解JVM的内部机制,可以让我们写出科学的Java程序。

上一篇: 无

微信关注

获取更多技术咨询