JVM(一):Java内存区域
1、程序计数器
- 每个线程内存私有,互不影响;
- 是一块内存较小的空间,可看作当前线程所执行字节码的行号指示器;字节码指示器通过改变程序计数器的值实现代码流程控制;
- 唯一一个不会出现OutOfMemoryError的内存区域,随线程创建而创建,随线程终止而死亡。
2、虚拟机栈
- 线程私有
- 通过栈帧描述方法执行的过程;每一个栈帧包括局部变量表、操作数栈、动态链接、方法出口信息;
- 局部变量表存放了编译器可知的各种数据类型和对象引用,每一个方法的开始执行和结束对应着栈帧的入栈和出栈;
- 会出现StackOverFlowError和OutOfMemoryError(StackOverFlowError:虚拟机栈内存大小不允许动态扩展,当线程请求的栈深度超过当前虚拟机栈最大深度时,会抛出此异常;OutOfMemoryError:虚拟机栈允许动态扩展内存,当线程请求栈时内存用完无法再动态扩展时会抛出此异常)
3、本地方法栈
- 与虚拟机栈作用类似,只不过虚拟机栈为虚拟机执行Java方法,本地方法栈为虚拟机使用到的Naive方法服务;
4、堆
- 线程共有的
- 在虚拟机启动时创建,存放对象实例与数组
- 垃圾收集器管理的主要区域,也被称为GC堆;可分为新生代和老年代,新生代可分为eden、s0、s1
5、方法区/永久代/元空间
- 线程公有
- 存储类的信息、常量池、方法数据、代码等;
- 永久代是HotSpot虚拟机对虚拟机规范中方法区的一种具体实现;
- JDK7及以前:永久代;内存中永不会GC,加载了类信息和元数据信息;空间被加载的类信息占满会发生OutOfMemoryError;
- JDK8及以后:元空间;直接使用了本地内存;