java eden分配参数,JVM垃圾收集器与内存分配策略,

垃圾收集器与内存分配策略

对象存活判断

引用计数算法

给对象添加一个计数器,每有一个引用+1,当引用失效-1,若为0则不在被使用.

可达性分析算法

对象是否可到达GC roots

或者说GC roots 是否是对象的上层节点(祖父节点,父节点)

GC roots

虚拟机栈(栈中的本地变量表)中引用的对象

方法区中类静态属性引用的对象

方法区中常量引用的对象

本地方法栈中引用的对象

引用

如果reference类型的数据中存储的数值代表另一块的起始地址就称这块内存代表着一个引用(白话:栈中的reference保存的是一个内存起始地址)

强引用

永远不会被回收,最常用的

软引用

SoftReference 在将要发生内存溢出前被标记,下次GC时回收

弱引用

Weakreference每次GC都回收

虚引用

PhantomReference 无法通过虚引用得到一个对象的实例,唯一目的,当回收时收到一个系统通知

生存与死亡

可达性分析--不可达-->标记---->筛选--1.是否覆盖了finalize();方法 2.finalize()是否被调用过--->(1.未覆盖 2.非首次调用) 没必要执行

常见的垃圾收集算法

标记-清除算法

概念: 标记出需要回收的对象,统一回收标记对象

缺点

1.标记与清除效率都不高

2.清除后会有大量不连续的空间碎片,当分配内存需要的连续空间不足又会导致提前GC

复制算法

概念:将内存分为两块(即为A,B),先在A中存储,当A满了将回收,回收后将保留对象复制到B,清空A,后续在B中存储新的对象,B满了.往复 (S0,S1的实现)

缺点

1.将内存一分为2,假设10M内存则无法保存5M以上 10M以下的对象

2.存活率高的对象会导致来回复制,消耗性能,效率变低

标记-整理算法

概念:标记需要回收的对象,非标记对象像一端移动,清理端点边界值后的内存

分代收集算法

概念:根据对象存活周期的不同将内存划分为不同的块.(新生代,老年代),在根据每个块的特性选择最合适的收集算法

新生代

对象存活率低,需要复制的存活对象少

复制算法

老年代

对象存活率高,复制开销大

标记-清理(整理)算法

HotSpot的算法实现

为了保持一致性,GC进行是必须停顿所有java执行线程,即 Stop The World

枚举根节点

在HotSpot的实现中,当类加载完成是,HotSpot将对象内偏移量上具体的数据计算出来,在特定的位置记录下栈和寄存器中哪些位置是引用,使用一组称为OopMap的数据结构,GC在扫描时就可直接扫描这些信息,而不需要全量扫描

安全点 safePoint

程序执行并非任何地方都可停顿,只有当达到安全点时才能暂停.(Stop The World)

中断方案

抢先中断

GC执行时,将所有线程中断,若发现不在安全点中断的线程就恢复这条线程,让其运行至安全点. 几乎已没有虚拟机采用这种方式

主动中断

不直接操作线程,而是对线程做标志,每个线程主动去轮询这个标志,当发现这个中断标志时自己中断挂起.

安全区域 safe Region

在一段代码片段中,引用关系不会发生变化,这个区域中任意地方开始GC都是安全的

线程--执行safe Region中代码--> 标记自己已进入safeRegion---离开SafeRegion-->检查系统是否完成跟节点枚举(或整个GC过程)

完成了线程继续进行

未完成,等待,直到收到可以离开SafeRegion的信号为止

垃圾收集器

Serial

JDK1.3.1以前,年轻代唯一的选择

单线程收集器,必须暂停其它所有工作线程,直到它收集结束

Client模式下默认的新生代收集器

优点:简单高效,没有线程交互开销

ParNew

多线程版本的Serial

Server模式下新生代首选收集器

优点:除了Serial以外,只有parNew可以与CMS配合工作

-XX:+UseConcMarkSweepGC 默认新生代收集器

-XX:+UserParNewGC 强制指定

Parallel Scavenge

使用复制算法,并行的多线程收集器

更关注于吞吐量,其它收集器关注缩短停顿时间(Stop The World)

吞吐量=运行用户代码时长/(运行用户代码时长+垃圾收集时长)

-XX:MaxGCPauseMillis 设置最大停顿时间(毫秒)

-XX:GCTimeRatio 设置吞吐量大小(0-100)

-XX:UseAdaptiveSizePolicy

配合最大停顿时间,或吞吐量来使用.仅需要设置-Xmx

GC自适应调节策略(与其它收集器的重要区别)

开启这个参数将不在需要手工指定

-Xmn,

-XX:SurvivorRatio,

-XX:PretenureSizeThreshold等细节参数,虚拟机会根据当前系统运行情况进行调节

Serial Old

单线程,老年代serial收集器,采用标记-整理算法

JDK1.5及以前与parallel Scavenge配合使用

作为CMS备选方案,当CMS发生 Concurrent Mode Failure时使用

Parallel Old

JDK1.6开始提供

Parallel Scavenge老年代版本,多线程,采用标记-整理算法

注重吞吐量及CPU资源敏感时使用

CMS

HotSpot第一款并发收集器,以获取最短回收停顿时间为目标的收集器

采用标记-清除算法

运作流程

1.初始标记

仅标记GC roots能够直接关联到的对象,速度快(Stop the World) 单线程

2.并发标记

进行GC roots Tracing

3.重新标记

修正并发标记期间因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录(Stop the World) 比初始标记时间长,比并发标记时间短 多线程

4.并发清除

缺点

对CPU资源非常敏感.默认启动回收线程数(CPU数量+3)/4,4个以上的CPU则会占用25%以上资源.占用资源过多

无法处理浮动垃圾,可能因Concurrent Mode Failure而导致一次Full GC的触发

浮动垃圾:并发时又产生的新垃圾

并发处理,则垃圾回收时需要预留内存供用户线程使用,JDK1.5默认68%即会触发GC,JDK1.6默认值为92%,

-XX:CMSInitiatingOccupancyFraction

来设置阀值

标记-清除算法

提供了一个参数:

-XX:+UseCMSCompactAtFullCollection

默认开启,FullGC后进行内存整理

-XX:CMSFullGCsBeforeCompaction

默认0即每次 设置多少次fullGC后整理一次内存

G1

JDK7u4正式商用

G1新生代,老年代的区分与其它收集器模式不同,它将内存划分成更多的Region,虽保留新生代,老年代概念,但已不在是物理隔离了,它们现在都是由Region(无需连续)组成的集合

特点

并行,并发

分代收集

空间整理

采用了标记-整理算法

可预测的停顿

G1将跟踪每一个Region中垃圾堆积的价值大小.在后台维护一个优先列表,每次根据允许的手机时间,优先回收价值最大的Region,以此来保证可预测的停顿时间,并达到最高的收集效率

在G1收集器中,有一个关键的概念,Remembered Set,每一个Region都一个对应的Remembered Set,每当程序对Reference类型数据进行了写操作时,虚拟机会产生一个Write Barrier暂时中断写操作,检查Reference引用的对象是否处于不同的Region中,如果是,则会通过CardTable将相关引用信息记录到被引用对象所属的Region中的Remembered Set中.

当进行内存回收时,GC跟节点枚举范围中加入Remembered Set 以保证不全堆扫描也不会遗漏

运作流程

初始标记

与CMS相同

并发标记

对堆中对象进行可达性分析,找出可达对象

最终标记

修正在并发标记期间用户程序继续运作而导致标记产生变动的那一部分对象的标记记录,虚拟机将这些对象变化记录在Remembered Set Logs中,并将Remembered Set Logs数据合并到Remembered Set中,停顿执行,但是可以并行执行

筛选回收

对每个Region的回收价值和成本进行排序,根据用户指定的停顿时间来制定回收计划,进行回收

内存分配及回收策略

进入Eden区,若不足触发minor GC

大对象直接进入老年代

大对象:一般指大于Survivor一半以上

长期存活的对象进入老年代(即对象年龄达到阀值默认15)

当一组对象年龄相同的对象大于Survivor区一半时,年龄大于或等于这个年龄的对象都将直接进入老年代

空间分摊担保

垃圾收集器常用参数

UseSerialGC

使用Serial+Serial Old 收集器

UseParNewGC

UseConcMarkSweepGC

使用parNew + CMS + Serial Old

UseParallelGC

UseParallelOldGC

SurvivorRatio

8:1

PretenureSizeThreshold

设置直接进入老年代对象的大小阀值

MaxTenuringThreshold

设置进入老年代的对象年龄.默认15

UseAdaptiveSizePolicy

由虚拟机动态调整java堆大小分配和进入老年代的对象年龄

HandlePromotionFailure

是否允许分配担保失败

ParallelGCThreads

设置并行GC时进行内存回收的线程数

GCTimeRatio

设置GC时间占比,默认99即允许GC占用1%时间

仅Parallel Scavenge 有效

MaxGCPauseMillis

最大停顿时间

仅Parallel Scavenge 有效

CMSInitiatingOccupancyFraction

设置GMS在老年代被占用X时启动,默认68(JDK1.5) 92(JDK1.6)

UseCMSCompactAtFullCollection

CMS收集后是否整理

CMSFullGCsBeforeCompaction

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值