package com.yh.stu.jvm.garbage; import java.util.*; /** * 实现一个GCRoots算法 * * @author DSH * @create 2019-08-05-15:17 */ public class GCRootsTest { private static TraceTable traceTable = new TraceTable(); private static StackFrame stackFrame = new StackFrame(); private static Generation newGeneration = new Generation(); private static Generation oldGeneration = new Generation(); public static void main(String[] args) { /** * 在年轻代放入10000个对象 ,存活100个 */ final int totalNewObjAmt = 10_000; for (int i = 0; i < totalNewObjAmt; i++) { ObjectStorageStructure objSt = new ObjectStorageStructure("#A000-"+i, "A000"+i); newGeneration.add(objSt); } /** * 在老年代代放入10000个对象 ,存活9900个 */ final int totalOldObjAmt = 10_000; for (int i = 0; i < totalOldObjAmt; i++) { ObjectStorageStructure objSt = new ObjectStorageStructure("#B000-"+i, "A000"+i); oldGeneration.add(objSt); } createRealation(newGeneration, 10); createRealation(oldGeneration, 990); System.out.print("Minor gc cost:"); newGeneration.gc(); System.out.println("=================================================="); System.out.print("Major gc cost:"); oldGeneration.gc(); } /** * 随机建立对象的引用关系 */ private static void createRealation(Generation generation, int childrenPerObj) { for (int i = 0; i < 10; i++) { ObjectStorageStructure objStRoot = getRandomObjFromGen(generation); stackFrame.addAddr(objStRoot.addr); for (int j = 0; j < childrenPerObj; j++) { ObjectStorageStructure objStChild = getRandomObjFromGen(generation); objStRoot.addRefObj(objStChild); addTraceTable(objStRoot, objStChild); } } } private static void addTraceTable(ObjectStorageStructure objStRoot, ObjectStorageStructure objStChild) { List<String> headList = traceTable.headMap.get(objStRoot.addr); if (headList == null) { headList = new ArrayList<>(); } headList.add(objStChild.addr); traceTable.headMap.put(objStRoot.addr, headList); } private static ObjectStorageStructure getRandomObjFromGen(Generation generation) { Random random = new Random(); List<ObjectStorageStructure> objStList = generation.getObjStList(); int randomIndex = random.nextInt(objStList.size()); ObjectStorageStructure objSt = objStList.get(randomIndex); return objSt; } public static String getUUID() { return UUID.randomUUID().toString(); } private static void execute() { stackFrame.addAddr(UUID.randomUUID().toString()); } static class Generation { private List<ObjectStorageStructure> objStList = new ArrayList<>(); private Map<String, ObjectStorageStructure> map = new HashMap<>(); public void gc() { TimerTools timerTools = new TimerTools(); timerTools.start(); //复制对象,这里用sleep(1)表示复制的时间消耗 int i = 1; for (String rootAddr : stackFrame.getVarAddrList()) { List<String> addrList = traceTable.headMap.get(rootAddr); for (String childAddr : addrList) { if (map.get(childAddr) != null) { try { Thread.sleep(0,0); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println((i++) + "-" + map.get(childAddr)); } } } System.out.println(timerTools.spent()); } public void add(ObjectStorageStructure objSt) { this.objStList.add(objSt); this.map.put(objSt.addr, objSt); } public List<ObjectStorageStructure> getObjStList() { return objStList; } } static class TraceTable { private Map<String, List<String>> headMap = new HashMap(); } static class StackFrame { private List<String> varAddrList = new ArrayList<>();//存放对象引用地址 /** * 在栈帧中放入对象引用地址 * * @param addr */ public void addAddr(String addr) { this.varAddrList.add(addr); } public List<String> getVarAddrList() { return varAddrList; } } static class ObjectStorageStructure { private String addr; private Object obj; private List<ObjectStorageStructure> refObjList = new ArrayList<>();//引用对象 public ObjectStorageStructure(String addr, Object obj) { this.addr = addr; this.obj = obj; } public void addRefObj(ObjectStorageStructure objSt) { refObjList.add(objSt); } @Override public String toString() { return "ObjectStorageStructure{" + "addr='" + addr + '\'' + ", obj=" + obj + '}'; } } }