内存简介
- 32位处理器:2^32 的可寻址范围
- 64位处理器:2^64 的可寻址范围
地址空间的划分
- 内核空间
- 用户空间
JVM架构图
- Class Loader:依据特定格式,加载class文件到内存
- Execution Engine:对命令进行解析
- Native Interface:融合不同开发语言的原生库为Java所用
- Runtime Data Area:JVM内存空间结构模型
JVM内存模型——JDK8
- 线程私有:程序计数器、虚拟机栈、本地方法栈
- 线程共享:MetaSpace、Java堆
程序计数器(Program Counter Register)
- 当前线程所执行的字节码行号指示器(逻辑)
- 改变计数器的值来选取下一条需要执行的字节码指令
- 和线程是一对一的关系即 “线程私有”
- 对Java方法计数,如果是Native方法则计数器值为Undefined
- 不会发生内存泄漏
Java虚拟机栈(Stack)
-
Java方法执行的内存模型
-
包含多个栈帧
局部变量表和操作数栈 -
局部变量表:包含方法执行过程中的所有变量
-
操作数栈:入栈、出栈、复制、交换、产生消费变量
执行add(1,2)
public static int add(int a,int b){
int c = 0;
c = a + b;
return c;
}
递归为什么会引发java.lang.StackOverflowError异常
public class Fibonacci {
//F(0) = 0,F(1) = 1,当n>=2的时候,F(n) = F(n-1) + F(n-2)
//F(2) = F(1) + F(0) = 1, F(3) = F(2) + F(1) = 1+1 = 2
//F(0)-F(N) 依次为 0,1,1,2,3,5,8,13,21,34...
public static int fibonacci(int n){
if(n == 0) {return 0;}
if(n == 1) {return 1;}
return fibonacci(n - 1) + fibonacci(n - 2);
}
public static void main(String[] args){
System.out.println(fibonacci(0));
System.out.println(fibonacci(1));
System.out.println(fibonacci(2));
System.out.println(fibonacci(3));
System.out.println(fibonacci(9));
//如果我们获取的深一点,看是否获取的到结果
System.out.println(fibonacci(1000000));
}
}
- 递归过深,栈帧数超过虚拟栈深度
虚拟机栈过多会引发 java.lang.OutOfMemoryError异常
Exception in thread “main” java.lang.OutOfMemoryError:
unable to create new native thread
(不要尝试着去运行,小心炸了)
本地方法栈
- 与虚拟机相似,主要作用于标注了native方法