java程序执行流程
- 所有的java程序代码必须保存在*.java的文件之中(源代码)
- 然后使用javac.exe命令将其编译为*.class文件
- 最后利用java.exe命令在JVM进程之中解释此程序
- 当JVM将所需要的*.class文件加载到JVM进程之中需要一个类加载器(ClassLoader)
- 类加载器可以随意指定程序*.class文件的所在路径
- 考虑到操作系统之间移植性的问题,所有程序都要运行在JVM上
- 在java里面可以使用native实现本地C函数的调用
![]()
java内存管理
- 栈是运行时的单位,里面存储的信息都是跟当前线程相关的信息
- 堆是存储的单位,只是保存对象信息
![]()
java运行时数据区
- java所有的程序运行都在运行时数据区之中
- 在整个的运行时数据区之中,分为如下几个内存空间
- 堆内存:保存所有引用数据类型的真实信息
- 栈内存:基本类型、运算、指向堆内存的指针
- 方法区:所有定义的方法的信息都保存在方法区之中,此区属于共享区
- 程序计数器:是一个非常小的内存空间,作用是当前线程所执行的字节码的行号指示器
- 本地方法栈:每一次执行递归的方法处理的时候实际上都会将上一个方法入栈
![]()
java虚拟机栈(Java Virtual Machine Stack)
- 栈内存是线程私有的,其生命周期和线程相同
- 虚拟机栈描述的是java方法执行的内存模型
- 执行一个方法是会产生一个栈帧,随后将其保存到栈的顶部(后进先出)
- 方法执行完毕后会自动将此栈帧进行出栈
- 顶部的栈帧就表示当前方法
- 如果请求的栈的深度过大,虚拟机可能会抛出StackOverflowError异常
- 如果虚拟机的实现中允许虚拟机栈动态扩展,但内存不足以扩展时,会抛出OutOfMemoryError异常
![]()
java虚拟机栈--栈帧(Stack Frame)
- java虚拟机栈会存放的是多个栈帧,主要组成部分为
- 局部变量表(Local Variables):
- 方法的局部变量或形参,其变量槽为最小单位,只允许保存32位长度的变量
- 如果超过32位,则会开辟两个连续的solt(64位长度,long和double)
- 操作数帧(Openrand Stack):
- 表达式计算在栈中完成
- 指向当前方法所属的类的运行时常量池的引用(Reference to runtime constant pool):
- 引用其他类的常量或者使用String池中的字符串
- 方法返回地址(Return Address):
- 方法执行完后需要返回调用此方法的位置,所以需要在栈帧中保存方法返回地址