java模拟JVM的GCRoots追踪算法,对象可达性分析
Posted csldm
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java模拟JVM的GCRoots追踪算法,对象可达性分析相关的知识,希望对你有一定的参考价值。
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 + ‘‘;
以上是关于java模拟JVM的GCRoots追踪算法,对象可达性分析的主要内容,如果未能解决你的问题,请参考以下文章