逃逸分析:
分配
1:请求一个服务器的接口,会给本次请求分配一个线程
2:通过类加载器把本次接口需要调用的类,检查是否加载过,加载过直接使用,没加载需要加载到内存中。
3:判断对象是否可分配到栈内存中(逃逸分析:如果该对象没有逃逸:作用于域,可以分配栈内存中,否则堆内存。)
4: 内存分配:
- 指针碰撞 : 内存规整
- 本地线程分配缓冲(TLAB) :每个线程,会在堆内存中预先分配一块内存。(默认开启)
5:如果对象存到堆内存。
- 判断,当前对象是否是大对象,大对象,直接存到老年代(jvm垃圾回收器可以设定,大于等于阈值,属于大对象)
- 判断,当前对象在eden区有没有足够的空间分配,该对象会先尝试是否可以分配到Survivor区。 如果该对象大于等于 Survivord的50%(该值可以设定) 也会直接存到老年代,如果小于就会存到Survivor
- 以上不存在,会直接存到eden区
对象在什么阶段会分配到老年代:
- 判断,当前对象是否是大对象,大对象,直接存到老年代(jvm垃圾回收器可以设定,大于等于阈值,属于大对象)
- 判断,当前对象在eden区有没有足够的空间分配,该对象会先尝试是否可以分配到Survivor区。 如果该对象大于等于 Survivord的50%(该值可以设定) 也会直接存到老年代,如果小于就会存到Survivor
- 执行Yong gc,如果eden区域存活的对象大于Survivord的50%,会直接存到老年代
- Survivord中的对象,分代年龄到达阈值,该对象会存到老年代
- Survivord中的对象,对象总和大于Survivord的50%,但是还没有到分代阈值,会把最大年代的对象移动老年代
什么样的对象会被垃圾回收:
没有被引用的对象,会被认为是垃圾对象
- 引用计数法:每当有一地方引用该对象,计数器加1,引用失效减1.。当为0就是垃圾对象.(目前虚拟机没用这个算法管理)
- 卡达性分析算法(jvm机默认):Gc root作为初始的对象集合,从该集合出发,能够被该集合对象引用的对象加入到集合中。 最后没有被引用的便是可回收的对象
老年代空间分配担保机制:
在执行yong gc之前。
- 判断老年代可用对象,是否大于年轻代所有对象总和。 如果大于直接yong GC (不执行full GC)
- 如果老年代小于,判断是否开启分配担保机制,如果已经开启,再判断所有yong gc执行后存到老年代,对象的平均值。
- 如果老年代的可用空间大于平均值,执行yong gc
- 如果老年代的可用空间小于于平均值,先执行,full gc,再执行yong gc
如果对象移动到老年代,老年代空间不足,报OOM (内存溢出)