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