用两个列表维护新生代 / 老年代对象 id,并用哈希表存每个对象的 cnt 与是否可回收。
youngSize,立即执行新生代 GC。cnt++ → cnt>=2 晋升老年代。cnt++(不晋升)。(-cnt, -id) 排序输出。实现类 GCSystem:对象分属新生代、老年代两个区域。每个对象有状态(可回收 / 不可回收)与整数 cnt(已经历的 GC 次数)。
新生代 GC(手动触发,或加入对象后新生代数量 ≥ 阈值时自动触发):
cnt 各加 1;cnt\ge 2 的对象移入老年代。老年代 GC(仅手动触发):删除老年代可回收对象;剩余对象 cnt 各加 1(不向别处迁移)。
接口:
GCSystem(int youngSize):初始化,youngSize 为新生代数量阈值createObject(int objectId):在新生代创建对象,cnt=0,不可回收;加入后可能触发新生代 GCmarkObjects(int[] objectIds):将给定对象标为可回收manualGC(int generation):0 新生代 / 1 老年代,手动 GCgetLiveObjects(int generation):返回该区域存活对象 id;按 cnt 降序,cnt 相同则 objectId 降序;空则 []每行一次调用;首行只能是一次 GCSystem。objectId 全局唯一;markObjects 中的 id 均已存在。
按调用顺序输出:GCSystem / createObject / markObjects / manualGC 为 null;getLiveObjects 为对象 id 列表。
输入:
GCSystem(2)
createObject(5)
createObject(6)
getLiveObjects(0)
markObjects([5])
createObject(7)
getLiveObjects(0)
getLiveObjects(1)
manualGC(1)
getLiveObjects(1)
输出:
null
null
null
[6, 5]
null
null
[7]
[6]
null
[6]
说明:
创建 6 后新生代满 2,触发 GC,5,6 的 cnt 变为 1。标记 5 后再创建 7 触发 GC:回收 5;6 的 cnt 变为 2 并晋升;7 留在新生代。手动老年代 GC 使 6 的 cnt 变为 3。
输入:
GCSystem(3)
createObject(1)
createObject(2)
createObject(3)
getLiveObjects(0)
createObject(4)
getLiveObjects(0)
getLiveObjects(1)
输出:
null
null
null
null
[3, 2, 1]
null
[4]
[3, 2, 1]
说明:
创建 3 时满阈值触发 GC,三者 cnt=1。再创建 4 再次 GC 后,1,2,3 晋升老年代,新生代仅剩 4。
Scan the QR code below with WeChat to sign in
First-time scan will create your account automatically
请使用微信扫描下方二维码完成注册