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(老年代)收集器配合使用
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使用的
java虚拟机管理的内存
程序计数器
线程私有的内存:生命周期与线程相同
唯一一个不会产生OutOfMemoryError异常的区域
字节码解释器通过程序计数器来选取下一条需要执行的字节码指令,比如:循环、跳转、异常处理、线程恢复等功能
栈
java虚拟机栈
java虚拟机栈描述的是方法执行的内存模型
方法执行时--创建栈帧
栈帧的作用:用于存储局部变量表、操作数栈、动态链接、方法出口等信息
局部变量表
局部变量表存放了编译器可知的各种基本数据类型(boolean、byte、char、short、int、float、long、double)
局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时需要在栈帧中分配多大局部变量是完全确定的
long和double会占用2个局部变量空间,其余的数据类型只占用1个
操作数栈
动态链接
方法出口
可能产生的异常是:StackOverflowError和OutOfMemoryError
本地方法栈
与java虚拟机栈类似,本地方法栈则为虚拟机使用到的Native方法服务
堆
java堆(GC堆)
虚拟机启动时创建
java堆唯一的目的就是存放对象实例
堆的扩展:-Xmx 和 -Mms 控制
堆也可以细分为:新生代(Eden空间、From Survivor空间、To Survivor空间)和老年代
方法区
与java堆类似
用于存储虚拟机加载的类信息、常量、静态变量、即时编译器后的代码等数据
方法区也可以称为:永久代
内存上限的控制:-XX:MaxPermSize
这部分GC回收目标主要是针对常量池的回收和类型的回收
回收类型的满足条件
该类所有实例都已被回收
加载该类的ClassLoader已被回收
该类对应的java.lang.Class对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法
回收常量的满足条件
常量没有在其它地方有引用
可能产生的异常是:OutOfMemoryError
运行时常量池
存放常量信息
常量是可以在运行期放入的也可以是编译器放入的
直接内存
NIO使用的是直接内存
JIT(Just-In-Time Compiler):即时编译器,将字节码转换成处理器可处理的程序
JNI(Java Native Interface):它提供了若干的API实现了Java和其他语言的通信
0 条评论
下一页