Context 的静态内存泄漏
我一直在做一些研究,但我仍然不能 100% 确定这是否会导致基于 内存泄漏。我正在使用按钮视图(v.context)。我认为我没问题,因为上下文没有存储为静态,但如果可能的话,我希望得到一些反馈。我看到的主要问题是 OSMonitor...(M) 值不断上升。每次打开/关闭小部件以及屏幕旋转。
32M 43M 61M 77M 等等...
我不确定 (M) 是兆字节还是兆位。如果这是基于堆栈的,我假设兆比特 perhpa,因为大多数高端设备的堆栈(或其他)限制为 32/48 MB。
感谢您的反馈/额外的关注!
这是市场中的横幅应用程序,顺便说一句......
public class Globals {
public static final String PREF_NAME = "BannerPreferences";
public static final int MAX_TEXT_SIZE = 20;
// refresh ALL widgets loaded on the user's screens
// this could be for removing or adding 'pendingIntents or during bootup
public static void refreshAllWidgets(Context context) {
Logger.d("BANNER", "Globals:refreshAllWidgets");
invalidateWidgets(context, BannerWidget.class); // 1x4
invalidateWidgets(context, BannerWidget1x2.class);
invalidateWidgets(context, BannerWidget2x2.class);
}
// there has to be a API way to do this!! Until then, just loop thru all
// widget_provider classes..
private static void invalidateWidgets(Context context, Class<?> cls) {
ComponentName comp = new ComponentName(context, cls);
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(comp);
for (int i = 0; i < appWidgetIds.length; i++) {
BannerWidgetBase.updateAppWidget(context, appWidgetManager, appWidgetIds[i]);
}
appWidgetIds = null;
}
I've been doing some researching and I'm still not 100% certain if this could cause an based
memory leak. I'm using a button view (v.context). I think I'm OK since the context isn't stored as Static, but I'd like some feedback if possible. The main issue I'm seeing is with OSMonitor... the (M) value goes UP and UP and UP. With every open/close of the widget and on screen rotation.
32M
43M
61M
77M
etc...
I'm not sure if (M) is Megabytes or Megebits. If this is based on the stack, I'm assuming Megebits perhpas since most high end devices are limited to 32/48 MB on the stack (or something).
Thanks for the feedback/extra eyes!
This is the Banner app in the Market, btw...
public class Globals {
public static final String PREF_NAME = "BannerPreferences";
public static final int MAX_TEXT_SIZE = 20;
// refresh ALL widgets loaded on the user's screens
// this could be for removing or adding 'pendingIntents or during bootup
public static void refreshAllWidgets(Context context) {
Logger.d("BANNER", "Globals:refreshAllWidgets");
invalidateWidgets(context, BannerWidget.class); // 1x4
invalidateWidgets(context, BannerWidget1x2.class);
invalidateWidgets(context, BannerWidget2x2.class);
}
// there has to be a API way to do this!! Until then, just loop thru all
// widget_provider classes..
private static void invalidateWidgets(Context context, Class<?> cls) {
ComponentName comp = new ComponentName(context, cls);
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(comp);
for (int i = 0; i < appWidgetIds.length; i++) {
BannerWidgetBase.updateAppWidget(context, appWidgetManager, appWidgetIds[i]);
}
appWidgetIds = null;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
不一定有泄漏。由于Dalvik VM的性质,堆在使用时不断增长,直到达到最大堆大小。但是,堆中可能有足够的空间来容纳您的对象。我建议限制模拟器映像中的进程内存(堆),并查看是否确实遇到 OutOfMemoryError。创建模拟器时,您需要设置一个属性“最大VM应用程序堆大小”,例如32(以兆字节为单位)。
如果您遇到 OutOfMemoryError,您应该仔细查看 Eclipse MAT。
PS:刚刚意识到您可能应该在您的情况下使用应用程序上下文,而不是活动。如果您从活动中触发它,请考虑 getApplicationContext 而不是将 Activity 作为上下文传递。静态的东西可能比 Activity 实例的寿命更长。
There does not have to be a leak. Due to the nature of the Dalvik VM, the heap keeps growing when it is in use until it reaches the maximum heap size. However, there may be enough space in the heap for your objects. I'd suggest to limit the process memory (heap) in a emulator image and see if you actually get an OutOfMemoryError. When creating the emulator, there's a property "Max VM application heap size" you want to set, e.g. to 32 (measured in megabyte).
If you get an OutOfMemoryError, you should have a closer look at Eclipse MAT.
P.S.: Just realized that you should probably use an application context in your case, and never an Activity. If you trigger it from an activity, consider getApplicationContext instead of passing the Activity as a context. Static stuff may outlive Activity instances.