java虚拟机内存
2019-01-12 16:47:17 55 举报
AI智能生成
java虚拟机内存
作者其他创作
大纲/内容
对象的创建
类加载
为新生对象分配内存
分配内存的算法
指针碰撞
空闲列表
指针碰撞和空闲列表的选择
对象分配原则
优先在Eden分配,当没有足够空间时就进行一次MinorGC
“朝生夕灭”的“短命大对象”是最可怕的事情,遇到大对象可以直接放入老年代
当满足一定的年龄的对象(对象年龄计数器)就将其放到老年代中
当Survivor空间中相同年龄所有对象大小的总和大于Survivor空间的一半,就将其放入到老年代中
对象内存的布局
对象创建在并发时的安全性
第一种方式:CAS配上失败重试的方式保证更新操作的原子性
第二种方式:本地线程分配缓冲
虚拟机对对象进行设置
对象头
存储对象自身的运行时数据
对象的GC分代年龄等信息
偏向线程ID、线程持有的锁、锁状态的标志、哈希码
对象指向它的类元数据的指针
对齐填充
对象已死的判断
引用计数法
可达性分析算法
可作为GC Roots的对象
虚拟机栈中的栈帧的本地变量表
方法区中类静态属性引用的对象
方法区中常量引用的对象
本地方法栈中JNI引用的对象
宣告对象死亡
至少要经历两次标记过程
第一次标记,使其覆盖finalize()方法
当一个对象覆盖了finalize()方法,就将其放入F-Queue的队列中
GC对F-Queue队列中的数据进行GC
引用
引用的定义
强引用
软引用
弱引用
虚引用
垃圾收集算法
标记-清除算法
适用老年代
复制算法
适用新生代
标记-整理算法
适用老年代
分代收集算法
在新生代和老年代采用不同的算法
HotSpot的算法实现
枚举根节点
安全点
安全区域
垃圾收集器
Serial收集器
适用于client模式下的新生代
单线程下新生代最佳选择
关注的是stop the world的时间
新生代采用复制算法
ParNew收集器
适用于Server模式下的新生代
多线程模式下新生代最佳选择
可以和jdk1.5的CMS(老年代)收集器配合使用
关注的是stop the world的时间
新生代采用复制算法
Parallel Scavenge收集器
多线程下的新生代收集器
使用的是复制算法
关注的是程序的吞吐量
不可以和jdk1.5的CMS(老年代)收集器配合使用
Serial Old收集器
适用于client模式下的老年代
使用的是标记-整理算法
Parallel Old收集器
适用于server模式下的老年代
使用的是标记-整理算法
CMS(Concurrent Mark Sweep)收集器
老年代的收集器
使用的是标记-清除算法
运作过程
1.初始标记
2.并发标记
3.重新标记
4.并发清除
优点
并发收集、低停顿
缺点
CMS收集器对CPU资源敏感
默认启动的回收线程数是(CPU数量+3)/4
CPU不足4个,对程序影响就会变大。因为还要分出一半的线程去执行GC
CMS收集器无法处理浮动垃圾
基于标记-清除算法,会产生大量空间碎片
通过-XX:+UseCMSCompactAtFullCollection开关参数配置是否开启内存碎片整理过程
通过-XX:CMSFullGCsBeforeCompaction参数来设置执行多少次不压缩的FullGC后来一次带压缩的FullGC
G1(Garbage First)收集器
jdk1.7使用的
程序计数器
线程私有的内存:生命周期与线程相同
唯一一个不会产生OutOfMemoryError异常的区域
字节码解释器通过程序计数器来选取下一条需要执行的字节码指令,比如:循环、跳转、异常处理、线程恢复等功能
栈
java虚拟机栈
线程私有的内存:生命周期与线程相同
java虚拟机栈描述的是方法执行的内存模型
方法执行时--创建栈帧
栈帧的作用:用于存储局部变量表、操作数栈、动态链接、方法出口等信息
局部变量表
局部变量表存放了编译器可知的各种基本数据类型(boolean、byte、char、short、int、float、long、double)
局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时需要在栈帧中分配多大局部变量是完全确定的
long和double会占用2个局部变量空间,其余的数据类型只占用1个
操作数栈
动态链接
方法出口
可能产生的异常是:StackOverflowError和OutOfMemoryError
本地方法栈
线程私有的内存:生命周期与线程相同
与java虚拟机栈类似,本地方法栈则为虚拟机使用到的Native方法服务
可能产生的异常是:StackOverflowError和OutOfMemoryError
堆
java堆(GC堆)
虚拟机启动时创建
java堆唯一的目的就是存放对象实例
堆的扩展:-Xmx 和 -Mms 控制
堆也可以细分为:新生代(Eden空间、From Survivor空间、To Survivor空间)和老年代
方法区
与java堆类似
用于存储虚拟机加载的类信息、常量、静态变量、即时编译器后的代码等数据
方法区也可以称为:永久代
内存上限的控制:-XX:MaxPermSize
这部分GC回收目标主要是针对常量池的回收和类型的回收
回收类型的满足条件
该类所有实例都已被回收
加载该类的ClassLoader已被回收
该类对应的java.lang.Class对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法
回收常量的满足条件
常量没有在其它地方有引用
可能产生的异常是:OutOfMemoryError
运行时常量池
存放常量信息
常量是可以在运行期放入的也可以是编译器放入的
可能产生的异常是:OutOfMemoryError
直接内存
NIO使用的是直接内存
JIT(Just-In-Time Compiler):即时编译器,将字节码转换成处理器可处理的程序
JNI(Java Native Interface):它提供了若干的API实现了Java和其他语言的通信
0 条评论
下一页