/******************************************************************************* * Copyright (c) 2002 - 2006 IBM Corporation. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package com.ibm.wala.util.ref; import java.lang.ref.WeakReference; import java.util.Iterator; import com.ibm.wala.classLoader.IClass; import com.ibm.wala.classLoader.IMethod; import com.ibm.wala.classLoader.ShrikeCTMethod; import com.ibm.wala.classLoader.ShrikeClass; import com.ibm.wala.ipa.callgraph.AnalysisCache; import com.ibm.wala.ipa.cha.IClassHierarchy; /** * For some reason (either a bug in our code that defeats soft references, or a * bad policy in the GC), leaving soft reference caches to clear themselves out * doesn't work. Help it out. * * It's unfortunate that this class exists. */ public class ReferenceCleanser { private final static float OCCUPANCY_TRIGGER = 0.5f; private static WeakReference<IClassHierarchy> cha; private static WeakReference<AnalysisCache> cache; public static void registerClassHierarchy(IClassHierarchy cha) { ReferenceCleanser.cha = new WeakReference<IClassHierarchy>(cha); } private static IClassHierarchy getClassHierarchy() { IClassHierarchy result = null; if (cha != null) { result = cha.get(); } return result; } public static void registerCache(AnalysisCache cache) { ReferenceCleanser.cache = new WeakReference<AnalysisCache>(cache); } private static AnalysisCache getAnalysisCache() { AnalysisCache result = null; if (cache != null) { result = cache.get(); } return result; } /** * A debugging aid. TODO: move this elsewhere */ public static void clearSoftCaches() { float occupancy = 1f - ((float)Runtime.getRuntime().freeMemory() / (float)Runtime.getRuntime().totalMemory()); if (occupancy < OCCUPANCY_TRIGGER) { return; } AnalysisCache cache = getAnalysisCache(); if (cache != null) { cache.getSSACache().wipe(); } IClassHierarchy cha = getClassHierarchy(); if (cha != null) { for (IClass klass : cha) { if (klass instanceof ShrikeClass) { ShrikeClass c = (ShrikeClass) klass; c.clearSoftCaches(); } else { for (Iterator it2 = klass.getDeclaredMethods().iterator(); it2.hasNext(); ) { IMethod m = (IMethod)it2.next(); if (m instanceof ShrikeCTMethod) { ((ShrikeCTMethod)m).clearCaches(); } } } } } } }