浏览 5026 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2011-10-25
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); } } } } 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2011-10-25
使用时只要在Activity的onCreate方法里写一句:ActivityMemoryMonitor.setActivityToMonitoringQueue(this);
日志会写到data/data/程序包名/files目录下 |
|
返回顶楼 | |
发表时间:2011-10-25
ReferenceQueue Activity,2秒做一个 object == null 检测
|
|
返回顶楼 | |
发表时间:2011-10-25
嗯,是2秒做一个object != null的检测。
重点在PhantomReference,被内存级回收的对象才会加到ReferenceQueue里。 |
|
返回顶楼 | |
发表时间:2011-10-26
请问在什么样的情况下才会出现Activity Leaking ?
|
|
返回顶楼 | |
发表时间:2011-10-26
我特意去测试了,好像没有效果啊,还是报错。
10-26 02:06:33.311: ERROR/WindowManager(953): Activity com.mzba.im.ui.LoginActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@405e48a8 that was originally added here 10-26 02:06:33.311: ERROR/WindowManager(953): android.view.WindowLeaked: Activity com.mzba.im.ui.LoginActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@405e48a8 that was originally added here |
|
返回顶楼 | |
发表时间:2011-10-26
好吧,这个类只是监听Activity的内存回收情况,并写到日志中。所谓的防止,是你去看日志里看哪个Activity没有被回收,然后去找问题。
|
|
返回顶楼 | |