JVM 小白学习之四 :Java虚拟机内存管理
分类:
文章
•
2023-10-30 23:09:28
Java 虚拟机内存管理
- java运行时JVM中的数据区总览图。
1.1 程序计数器
- 程序计数器是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器。
- 程序计数器处于线程独占区。
- 如果线程执行的是Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址。如果正在执行的是native方法,这个计数器的值为undefined
- 此区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemory情况的区域,(因为开发者不需要去操作这一块内存)
- 每个线程都有其自己的程序计数器。
- java中现在暂时不能使用goto,其是java中的保留字
1.2 虚拟机栈
- 虚拟机栈描述的是Java方法执行的动态内存模型
- 栈帧
- 每个方法执行,都会创建一个栈帧,伴随着方法从创建到执行完成。用于存储局部变量表,操作数栈,动态链接,方法出口等。
- 局部变量表
- 存放编译器可知的各种基本数据类型,引用类型,returnAddress类型
- 局部变量表的内存空间在编译器完成分配,当进入一个方法时,这个方法需要在帧分配多少内存是固定的,在方法运行期间是不会改变局部变量表的大小的。因为其只存 引用。
- 大小
- 虚拟机栈不够存放栈帧,则会出现StackOverflowError,递归中常出现这种错误。
- 如果设置栈的空间非常大,则可能出现OutOfMemoryError
1.3 本地方法栈
- HotSpot内存区域不区分虚拟机栈和本地方法栈,但大多都是有区分
- 虚拟机栈是为虚拟机执行Java方法服务
- 本地方法栈为虚拟机执行native方法服务
- 其他方法虚拟机栈相同类似
1.4 Java堆
- 存放对象实例
- 垃圾收集器管理的主要区域
- 新生代,老年代,Eden空间
- Java虚拟机中管理的最大的内存区域(内又分为几个区域)
- OutOfMemory
- 两个重要的参数 -Xms -Xmx 调整虚拟机内存的初始值最小值和最大值。
1.5 方法区
- 存储虚拟机加载的类的信息,常量,静态变量,即时编译器编译后的代码等数据。
- 类的版本
- 字段
- 方法
- 接口
- 方法区和永久代,在总多使用HotSpot的人中,很多人都原意把方法区称之为永久代。因为HotSpot把GC扩展到方法区,也就是使用永久代来时实现方法区。好处就是重复使用堆的GC去管理方法。而许多虚拟机没有永久代的概念。
- 垃圾回收在方法区的行为,回收效率低,且消费大
- 异常的定义
- OutOfMemoryError
特殊内存区域
2.1 运行时常量池
- 属于方法区的一部分。
- 用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后存放到常量池中。
- 字符串就是一个典型的例子哩。其在方法区中会以一个区SET存在,SET的特性就是无序不重复。
- OutOfMemoryError
2.2 直接内存
- 并不是虚拟机运行时数据区的一部分
- 能分配堆外内存
- 受物理内存的限制,可能报 OutOfMemoryError