JVM垃圾处理机制
Posted Kirl z
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JVM垃圾处理机制相关的知识,希望对你有一定的参考价值。
JVM垃圾处理机制(一)
1. JVM 简介
JVM: 被裁剪过的虚拟机, 执行字节码指令集的软件
java代码, java进程, jvm之间的关系
1.1 类加载
如果一个类没有发生类加载, 要先执行类加载
加载的时机:
- new对象
- 读, 写静态变量
- 调用静态方法
- 父类的类加载: 子类要初始化类加载, 如果父类还没有类加载, 则先执行父类的类加载
- 主函数的类: java 类名启动入口类
加载做的事情:
- 把字节码 (二进制数据) 加载到 java 进程的方法区 (类型的信息, 方法信息等等)
- 在堆中, 生成一个 Class 类对象, 作为方法区类信息 (代码数据) 访问的入口
加载字节码的来源: 不限于class文件, 还可以从其他的地方获取
1.2 关于 JVM
- JVM 是定制过的裁剪了部分功能的虚拟机, 模拟硬件执行字节码指令(将字节码翻译为机器码)
- java 进程启动时, 就会创建一个 java 虚拟机, 解释执行字节码指令, 还存在 JIT 即时编译器(运行期,
把热点代码编译为机器码, 之后就不用每次执行都要翻译, 提高效率), 最终是申请系统调度 CPU 执行机器码 - 不同虚拟机实现, 可以运行符合字节码规范的代码
基于自己独有的编译器, 编译为符合规范的字节码文件, 使用符合 java 虚拟机规范, 自己定制的 java 虚拟机来运行 (解释, 翻译为机器码)
2. 运行时数据区域
- 线程私有区域:程序计数器、Java虚拟机栈、本地方法栈
- 线程共享区域:Java堆、方法区、运行时常量池
线程共享区域, 都是 java 进程启动就会创建
2.1 内存溢出 (OOM)
创建变量/对象/类加载, 需要先在对应的内存区域, 分配一块内存空间, 如果该区域内存不足, 需要执行 gc (垃圾回收), 如果 gc 以后, 内存还是不够, 就会出现内存溢出
结果: 严重的情况, 整个 java 进程挂掉了
解决方案:
- 优化代码 (空间复杂度): 复用变量等
- java进程启动时, 加大对应内存区域的空间
- 如果系统内存不足以满足第2个条件, 还可以加大系统内存
2.2 程序计数器 (线程私有)
程序计数器是一块比较小的内存空间, 可以看做是当前线程所执行的字节码的行号指示器
目的:线程切换出去后, 要恢复时, 下个指令从哪个地方开始执行
不会内存溢出(OOM)
2.3 java 虚拟机栈 (线程私有)
虚拟机栈描述的是Java方法执行的内存模型 : 每个方法执行的同时都会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从调用直至执行完成的过程,就对应一个栈帧在虚拟机栈中入栈和出栈的过程。
局部变量表: 存放了编译器可知的各种基本数据类型(8大基本数据类型)、对象引用。
java 虚拟机栈的生命周期与线程相同: 线程启动, 虚拟机栈就创建, 线程销毁, 虚拟机栈也销毁 (出栈自动销毁栈帧, 不需要gc)
栈帧: 一个线程在执行一个方法的时候, 进入方法(创建栈帧, 入栈), 方法返回 (出栈) 生命周期: 和线程执行某个方法的时间相同
可能出现的异常:
- StackOverFlowError 异常 : 线程调用的方法链太深 (线程请求的栈深度/栈帧数量 远大于虚拟机允许的深度)
- OOM
2.4 本地方法栈 (线程共享)
本地方法栈与虚拟机栈的作用完全一样,他俩的区别无非是本地方法栈为虚拟机使用的Native方法服务,而虚拟机栈为JVM执行的Java方法服务。
2.5 java 堆 (线程共享)
Java堆(Java Heap)是JVM所管理的最大内存区域。Java堆是所有线程共享的一块区域,在JVM启动时创建。此内存区域存放的都是对象实例。JVM规范中说到:“所有的对象实例以及数组都要在堆上分配”。
启动时, 分配堆的内存为最小值, 创建对象空间不足, 就扩展, 如果扩展到最大值且gc后还不够, 就OOM
2.6 方法区 (线程共享)
方法区用于存储已被虚拟机加载的类信息, 常量, 静态变量, 即时编译器编译后的代码等数据
存在gc: 回收常量和类型
类型卸载的条件是非常苛刻的, 所以方法区的gc频率/效率是比较低
没有方法回收区, 就会经常出现 OOM
2.7 运行时常量池 (方法区的一部分)
运行时常量池是方法区的一部分,存放字面量与符号引用。
字面量 : 字符串(JDK1.7后移动到堆中) 、final常量、基本数据类型的值。
符号引用 : 类和结构的完全限定名、字段的名称和描述符、方法的名称和描述符。
以上是关于JVM垃圾处理机制的主要内容,如果未能解决你的问题,请参考以下文章