JVM内存管理模型

Java程序执行流程

Java内存管理

JVM中的运行时数据区包括:

(1)  程序计数器(program counter register)    

  记录程序的执行顺序,标记程序下一步要执行代码的顺序号, 占用一块很小的内存,基本上可以忽略不记..

(2) Java栈(stack)

  保存堆内存地址,基本数据,方法的执行;

(3) 本地方法栈(native method stack)

  保存操作系统的原生函数

(4) 方法区(method area)

  保存所有方法的具体操作,该区域属于共享区域

(5) 堆(heap) 

  保存真正的程序数据部分

栈是运行时的单位, 而堆是存储的单元

(1) 栈因为是运行单位, 里面存储的信息都是跟当前线程(或程序)相关的信息. 包括局部变量,程序运行状态 , 方法返回值等;

(2) 堆只是保存对象信息

在整个jvm内存组成的五部分中,栈内存是非常重要的一部分.

Java 虚拟机栈会存放多个栈帧,每个栈帧又包括如下几部分:

1. 局部变量表: 方法的局部变量或形参, 其以变量槽(slot)为最小单位, 只允许保存32位长度的变量,如果超过32位,则会开辟两个连续的槽(64位长度, long, double)

2. 操作数栈(operand Stack) : 指令执行的地方

3. 指向当前方法所属的类的运行时常量池的引用(reference to runtime constant pool) : 引用其它类的常量或者使用String池中的字符串;

4. 方法返回地址(return address ) : 方法执行完后需要返回调用此方法的位置,所以需要在栈帧中保存方法返回地址

Stack有两个常见的异常

1. java.lang.StackOverflowError 简称 SOE  , 当请求栈的深度过大时会抛此异常, 比例递归调用

public class StackTest {
    public static  int count = 0;
    public static void main(String[] args) {
        print();
    }
    public static void print() {
        System.out.println(count++);
        print();
    }
}
Exception in thread "main" java.lang.StackOverflowError
	at sun.nio.cs.UTF_8$Encoder.encodeLoop(UTF_8.java:691)
	at java.nio.charset.CharsetEncoder.encode(CharsetEncoder.java:579)
	at sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:271)
	at sun.nio.cs.StreamEncoder.write(StreamEncoder.java:125)
	at java.io.OutputStreamWriter.write(OutputStreamWriter.java:207)
	at java.io.BufferedWriter.flushBuffer(BufferedWriter.java:129)
	at java.io.PrintStream.write(PrintStream.java:526)
	at java.io.PrintStream.print(PrintStream.java:597)

  

2. 如果虚拟机的实现中允许虚拟机动态扩展,当内存不足以扩展栈的时候,会抛出OutOfMemoryError异常,简称OMM

原文地址:https://www.cnblogs.com/z-qinfeng/p/12208023.html