1 17 package org.alfresco.repo.cache; 18 19 import java.io.ByteArrayOutputStream ; 20 import java.io.IOException ; 21 import java.io.ObjectOutputStream ; 22 import java.io.Serializable ; 23 import java.util.List ; 24 25 import net.sf.ehcache.Cache; 26 import net.sf.ehcache.CacheException; 27 import net.sf.ehcache.CacheManager; 28 import net.sf.ehcache.Element; 29 30 import org.alfresco.error.AlfrescoRuntimeException; 31 import org.apache.commons.logging.Log; 32 import org.apache.commons.logging.LogFactory; 33 import org.quartz.Job; 34 import org.quartz.JobExecutionContext; 35 import org.quartz.JobExecutionException; 36 37 44 public class EhCacheTracerJob implements Job 45 { 46 private static Log logger = LogFactory.getLog(EhCacheTracerJob.class); 47 48 private CacheManager cacheManager; 49 50 56 public void setCacheManager(CacheManager cacheManager) 57 { 58 this.cacheManager = cacheManager; 59 } 60 61 public void execute(JobExecutionContext context) throws JobExecutionException 62 { 63 try 64 { 65 if (logger.isDebugEnabled()) 66 { 67 execute(); 68 } 69 } 70 catch (Throwable e) 71 { 72 logger.error("Exception during execution of job", e); 73 } 74 } 75 76 private void execute() throws Exception 77 { 78 if (cacheManager == null) 79 { 80 cacheManager = CacheManager.getInstance(); 81 } 82 83 long maxHeapSize = Runtime.getRuntime().maxMemory(); 84 long totalSize = 0L; 85 String [] cacheNames = cacheManager.getCacheNames(); 87 logger.debug("Dumping EHCache info:"); 88 for (String cacheName : cacheNames) 89 { 90 Cache cache = cacheManager.getCache(cacheName); 91 if (cache == null) { 93 continue; 94 } 95 CacheAnalysis analysis = new CacheAnalysis(cache); 97 logger.debug(analysis); 98 totalSize += analysis.getSize(); 100 } 101 double sizePercentage = (double)totalSize / (double)maxHeapSize * 100.0; 103 String msg = String.format( 104 "EHCaches currently consume %5.2f MB or %3.2f percent of system VM size", 105 (double)totalSize / 1024.0 / 1024.0, 106 sizePercentage); 107 logger.debug(msg); 108 } 109 110 private static class CacheAnalysis 111 { 112 private Cache cache; 113 private long size = 0L; 114 115 public CacheAnalysis(Cache cache) throws CacheException 116 { 117 this.cache = cache; 118 if (this.cache.getStatus() == Cache.STATUS_ALIVE) 119 { 120 try 121 { 122 calculateSize(); 123 } 124 catch (Throwable e) 125 { 126 } 128 } 129 } 130 131 public synchronized long getSize() 132 { 133 return size; 134 } 135 136 @SuppressWarnings ("unchecked") 137 private synchronized void calculateSize() throws CacheException 138 { 139 List <Serializable > keys = cache.getKeys(); 141 for (Serializable key : keys) 142 { 143 Element element = cache.get(key); 144 size += getSize(element); 145 } 146 } 147 148 private long getSize(Serializable obj) 149 { 150 ByteArrayOutputStream bout = new ByteArrayOutputStream (1024); 151 ObjectOutputStream oos = null; 152 try 153 { 154 oos = new ObjectOutputStream (bout); 155 oos.writeObject(obj); 156 return bout.size(); 157 } 158 catch (IOException e) 159 { 160 logger.warn("Deep size calculation failed for cache: \n" + cache); 161 return 0L; 162 } 163 finally 164 { 165 try { oos.close(); } catch (IOException e) {} 166 } 167 } 168 169 public String getStatusStr() 170 { 171 switch (cache.getStatus()) 172 { 173 case Cache.STATUS_ALIVE: 174 return "ALIVE"; 175 case Cache.STATUS_DISPOSED: 176 return "DISPOSED"; 177 case Cache.STATUS_UNINITIALISED: 178 return "UNINITIALIZED"; 179 default: 180 throw new AlfrescoRuntimeException("Unknown cache status: " + cache.getStatus()); 181 } 182 } 183 184 public String toString() 185 { 186 double sizeMB = (double)getSize()/1024.0/1024.0; 187 long maxSize = cache.getMaxElementsInMemory(); 188 long currentSize = cache.getMemoryStoreSize(); 189 long hitCount = cache.getHitCount(); 190 long missCount = cache.getMissCountNotFound(); 191 double percentageFull = (double)currentSize / (double)maxSize * 100.0; 192 double estMaxSize = sizeMB / (double) currentSize * (double) maxSize; 193 194 StringBuilder sb = new StringBuilder (512); 195 sb.append(" Analyzing EHCache: \n") 196 .append("===> ").append(cache.getName()).append("\n") 197 .append(" Hit Count: ").append(String.format("%10d hits ", hitCount )) 198 .append(" | Miss Count: ").append(String.format("%10d misses ", missCount )).append("\n") 199 .append(" Deep Size: ").append(String.format("%10.2f MB ", sizeMB )) 200 .append(" | Current Count: ").append(String.format("%10d entries ", currentSize )).append("\n") 201 .append(" Percentage used: ").append(String.format("%10.2f percent", percentageFull)) 202 .append(" | Max Count: ").append(String.format("%10d entries ", maxSize )).append("\n") 203 .append(" Estimated maximum size: ").append(String.format("%10.2f MB ", estMaxSize )); 204 return sb.toString(); 205 } 206 } 207 } 208 | Popular Tags |