内存模型&分区
- Java虚拟机在运行Java程序时,会管理着一块内存区域:运行时数据区
- 在运行时数据区里,会根据用途进行划分:
- Java虚拟机栈(栈区)
- 本地方法栈
- Java堆(堆区)
- 方法区
- 程序计数器
1.Java堆内存
-
Java堆内存的定义:堆内存(Heap),是垃圾回收机制管理的主要区域,可以称为:GC堆
-
Java堆内存的作用:主要就是存放Java对象的实例
-
Java堆内存的特点:JVM内存中最大并且线程共享
-
Java堆内存出现的异常:OutOfMemoryError异常,堆内存中没有足够的内存完成对象实例的分配并且堆无法再继续扩展。
-
Java堆内存备注说明:
- 从内存回收的角度分为:新生代和老年代,如果深入在进行查询学习
- 从内存分配的角度相当于:多个线程私有的分配缓冲区
2.Java虚拟机栈
- Java虚拟机栈:栈内存(Stack),是Java方法执行的内存模型
- 栈内存的作用:存储Java方法执行时的局部变量
- 以帧栈的形式
- 含数据类型和对象的引用(地址)
- 方法执行结束后就释放
- 栈内存的特点:线程是私有的,生命周期与线程相同
- 栈内存常见的异常:
- OutOfMemoryError异常:虚拟机栈扩展时无法申请到内存空间
- StackOverflowError异常:线程请求栈深度 > 虚拟机所允许的深度
- 栈内存备注:
- 每个Java方法执行时都会创建一个栈帧
- 一个Java方法从被调用到执行完成 等价于 一个栈帧在虚拟机栈中的入栈到出栈
- 局部变量所需要内存空间在方法编译时就会完成分配,在方法运行时不会改变大小
3.本地方法栈
类似于Java虚拟机栈,与Java虚拟机栈区别在于:服务的对象
- Java虚拟机栈为执行Java方法服务;
- 本地方法栈为执行Native方法服务;(百度一下:Native方法是什么方法)
4.方法区
- 方法区是堆的一个逻辑部分,为了与Java堆区分,可以称为:“非堆”区域(None - Heap)
- 方法区的作用:存储已被虚拟机加载的 类信息、常量、静态变量等数据
- 方法区的特点:线程是共享的
- 方法区常见的异常:OutOfMemoryError异常,当方法区无法满足内存分配需求
- 方法区的备注:
- 该区域的内存回收主要是针对于运行时常量池和对类的卸载
- 又称“永久代”:回收条件苛刻,很少出现垃圾收集
运行时常量池单独说明
- 常量池是方法区的一部分
- 常量池的作用是:存放类文件的编译时生成的各种字面量&符号引用
- 常量池的特点是:动态性,运行时可以添加新的常量,例如:
java.lang.String类中的intern()方法
- 常量池常见的异常:OutOfMemoryError异常,当常量池无法申请到内存时
5.程序计数器
- 程序计数器是指当前线程所执行的字节码的行号指示器
- 程序计数器作用是实现异常处理、线程恢复等基础功能
- 程序计数器原理是通过改变计数器的值,来选取下一条执行的字节码指令
- 程序计数器的特点:A.线程是私有的 B.内存空间比较小
- 程序计数器常见的异常:唯一一个在JVM中无任何OutOfMemoryError的内存区域
- 程序计数器备注:
- 线程私有的内存区域
- 为了使用线程切换后恢复到正确的位置
- 每条线程都配有独立的程序计数器,各个线程互不影响
- 独立存储的内存区域
6.额外备注:直接内存
- 定义:NIO类(JDK1.4引入)中基于通道和缓冲区的I/O方式,通过使用Native函数库直接分配的堆外内存
- 特点:不受堆大小限制
- 应用场景:适用于频繁调用的场景
通过一个 存储在Java堆中的DirectByteBuffer对象 作为这块内存的引用 进行操作,从而避免在Java 堆和 Native堆之间来回复制数据,提高使用性能
这段需要有一些知识储备才好!
- 抛出的异常:OutOfMemoryError,即与其他内存区域的总和 大于 物理内存限制