文章目录
JDK1.7内存模型
JDK1.8内存模型
线程私有的内存区域
程序计数器
- 一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器。
Java虚拟机栈
- 每个方法执行的时候都会创建一个栈帧,用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法调用直至执行完成的过程,就对应着一个栈帧在虚拟机中入栈和出栈的过程。
- 一直所说的栈区就指的是这里的虚拟机栈,再详细一点说是虚拟机栈中局部变量表部分。此区域一般会产生两种异常:
- 线程请求的栈深度大于虚拟机栈所允许的深度 ,抛出StackOverFlowError异常。
- 虚拟机在动态扩展时申请不到足够内存,会抛出OOM(OutOfMemoryError)异常。
本地方法区
- 本地方法栈与虚拟机栈的作用完全一样,他俩的区别无非是本地方法栈为虚拟机使用的Native方法服务,而虚拟机栈为JVM执行的Java方法服务。
线程共享区域
Java堆
在JVM启动时创建,所有的对象实例及数组都要在堆上分配。
如果在堆上没有足够内存完成实例分配也无法再拓展时,抛出OOM异常。
方法区/元数据区
- 用于存储已被虚拟机加载的类信息、常量、静态变量、编译器编译后的代码数据等。
- 此区域的内存回收主要是针对常量池回收以及对类型的卸载。当方法区无法满足内存分配需求时抛出OOM异常。
运行时常量池
- 编译期以及运行期产生的常量放在运行时常量池。
- 这里的常量包括:基本类型、包装类型和String。
- 类加载时会查询字符串常量池,以保证运行时常量池所引用的字符串与字符串常量池中是一致的。
直接内存
- 直接内存的分配不会受到Java堆大小的限制,但是,既然是内存,肯定还是会受到本机总内存(包括RAM以及SWAP区或者分页文件)大小以及处理器寻址空间的限制。也可能导致OutOfMemoryError异常出现。
常量池的补充说明
常量池可分为Class文件常量池、运行时常量池、字符串常量池。
class文件常量池
class文件中除了有类的版本、字段、方法、接口等信息外,还有一项信息是常量池,用于存放编译期生成的各种字面量和符号引用,这些内容将在类加载之后进入方法区的运行时常量池存放。
运行时常量池
运行时常量池相对于Class文件常量池的另外一个重要特征是具备动态性,Java语言并不要求常量一定只有编译期才能产生,运行期间也可能将新的常量放入池中,这种特性利用的比较多的是String类的intern()方法。
字符串常量池
存储字符串对象,或是字符串对象的引用。