import java.io.BufferedOutputStream;
import java.io.Closeable;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.content.Context;
public final class ActivityMemoryMonitor
{
private final static ReferenceQueue<Activity> referenceQueue = new ReferenceQueue<Activity>();
private final static Map<PhantomReference<Activity>, String> phantomReferenceMap = new HashMap<PhantomReference<Activity>, String>();
private final static String logFile = "activity_memory_monitor.log";
private static Timer memoryMonitorTimer = null;
public static void setActivityToMonitoringQueue(Activity activity)
{
String activityInfo = activity.toString() + "." + activity.hashCode();
phantomReferenceMap.put(new PhantomReference<Activity>(activity, referenceQueue), activityInfo);
writeLogToFile(activity, "Activity Created: " + activityInfo);
startMonitoringIfNeeded(activity.getApplicationContext());
}
private static void startMonitoringIfNeeded(Context context)
{
if (memoryMonitorTimer != null)
{
return;
}
memoryMonitorTimer = new Timer();
memoryMonitorTimer.schedule(new MemoryMonitorTask(context), 0, 2000);
}
private static synchronized void writeLogToFile(Context context, String message)
{
FileOutputStream fos = null;
BufferedOutputStream out = null;
try
{
fos = context.openFileOutput(logFile, Context.MODE_APPEND);
out = new BufferedOutputStream(fos);
String log = new Date().toString() + " " + message + "\n";
out.write(log.getBytes());
} catch (IOException e)
{
} finally
{
close(out);
close(fos);
}
}
private static void close(Closeable c)
{
if (c == null)
{
return;
}
try
{
c.close();
} catch (IOException e)
{
}
}
private static class MemoryMonitorTask extends TimerTask
{
private Context context;
MemoryMonitorTask(Context context)
{
this.context = context;
}
@Override
public void run()
{
System.gc();
Object o = ActivityMemoryMonitor.referenceQueue.poll();
if (o != null)
{
writeLogToFile(context, "GC Cllected: " + phantomReferenceMap.get(o));
phantomReferenceMap.remove(o);
}
}
}
import java.io.Closeable;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.content.Context;
public final class ActivityMemoryMonitor
{
private final static ReferenceQueue<Activity> referenceQueue = new ReferenceQueue<Activity>();
private final static Map<PhantomReference<Activity>, String> phantomReferenceMap = new HashMap<PhantomReference<Activity>, String>();
private final static String logFile = "activity_memory_monitor.log";
private static Timer memoryMonitorTimer = null;
public static void setActivityToMonitoringQueue(Activity activity)
{
String activityInfo = activity.toString() + "." + activity.hashCode();
phantomReferenceMap.put(new PhantomReference<Activity>(activity, referenceQueue), activityInfo);
writeLogToFile(activity, "Activity Created: " + activityInfo);
startMonitoringIfNeeded(activity.getApplicationContext());
}
private static void startMonitoringIfNeeded(Context context)
{
if (memoryMonitorTimer != null)
{
return;
}
memoryMonitorTimer = new Timer();
memoryMonitorTimer.schedule(new MemoryMonitorTask(context), 0, 2000);
}
private static synchronized void writeLogToFile(Context context, String message)
{
FileOutputStream fos = null;
BufferedOutputStream out = null;
try
{
fos = context.openFileOutput(logFile, Context.MODE_APPEND);
out = new BufferedOutputStream(fos);
String log = new Date().toString() + " " + message + "\n";
out.write(log.getBytes());
} catch (IOException e)
{
} finally
{
close(out);
close(fos);
}
}
private static void close(Closeable c)
{
if (c == null)
{
return;
}
try
{
c.close();
} catch (IOException e)
{
}
}
private static class MemoryMonitorTask extends TimerTask
{
private Context context;
MemoryMonitorTask(Context context)
{
this.context = context;
}
@Override
public void run()
{
System.gc();
Object o = ActivityMemoryMonitor.referenceQueue.poll();
if (o != null)
{
writeLogToFile(context, "GC Cllected: " + phantomReferenceMap.get(o));
phantomReferenceMap.remove(o);
}
}
}
}
参考文章:http://www.iteye.com/topic/1117008
引出几个知识点:
Java 中一共有 4 种类型的引用 : StrongReference、 SoftReference、 WeakReference 以及 PhantomReference (传说中的幽灵引用 呵呵),
详细查看:http://www.douban.com/note/155272515/
小知识点:在内存中写文件
- private static synchronized void writeLogToFile(Context context, String message)
- {
- FileOutputStream fos = null;
- BufferedOutputStream out = null;
- try
- {
- fos = context.openFileOutput(logFile, Context.MODE_APPEND); //写在手机内存中
- out = new BufferedOutputStream(fos);
- String log = new Date().toString() + " " + message + "\n";
- out.write(log.getBytes());
- } catch (IOException e)
- {
- } finally
- {
- close(out);
- close(fos);
- }
- }