package com.jsonde.profiler.heap;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.util.*;
import java.util.concurrent.ThreadFactory;
public class HeapAnalyzer extends ReferenceQueue<Object> implements Runnable {
private Map<Long, ClassHeapData> heapData = Collections.synchronizedMap(
new HashMap<Long, ClassHeapData>());
private Set<Reference> references = Collections.synchronizedSet(
new HashSet<Reference>());
private Thread thread;
public HeapAnalyzer(ThreadFactory threadFactory) {
thread = threadFactory.newThread(this);
}
public void createObject(Object object, long constructorId, long objectSize) {
references.add(new HeapAnalyzerReference(object, this, constructorId, objectSize));
if (!heapData.containsKey(constructorId)) {
heapData.put(constructorId, new ClassHeapData());
}
heapData.get(constructorId).newObject(objectSize);
}
private volatile boolean running;
public void start() {
running = true;
thread.start();
}
public void stop() {
running = false;
try {
thread.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
public boolean isRunning() {
return running;
}
public void run() {
while (running) {
try {
Reference reference = remove(50);
if (null != reference) {
HeapAnalyzerReference heapAnalyzerReference = (HeapAnalyzerReference) reference;
Long constructorId = heapAnalyzerReference.getConstructorId();
heapData.get(constructorId).collectObject(heapAnalyzerReference.getObjectSize());
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
public Map<Long, ClassHeapData> getHeapData() {
//return new HashMap<Long, ClassHeapData>(heapData);
return heapData;
}
}