From article of android developers site :)
Android applications are, at least on the T-Mobile G1, limited to 16 MB of heap. It's both a lot of memory for a phone and yet very little for what some developers want to achieve. Even if you do not plan on using all of this memory, you should use as little as possible to let other applications run without getting them killed. The more applications Android can keep in memory, the faster it will be for the user to switch between his apps. As part of my job, I ran into memory leaks issues in Android applications and they are most of the time due to the same mistake: keeping a long-lived reference to a Context
.
On Android, a Context
is used for many operations but mostly to load and access resources. This is why all the widgets receive a Context
parameter in their constructor. In a regular Android application, you usually have two kinds of Context
, Activity
and Application
. It's usually the first one that the developer passes to classes and methods that need aContext
:
@Override
protected void onCreate(Bundle state) {
super.onCreate(state);
TextView label = new TextView(this);
label.setText("Leaks are bad");
setContentView(label);
}
This means that views have a reference to the entire activity and therefore to anything your activity is holding onto; usually the entire View hierarchy and all its resources. Therefore, if you leak the Context
("leak" meaning you keep a reference to it thus preventing the GC from collecting it), you leak a lot of memory. Leaking an entire activity can be really easy if you're not careful.
When the screen orientation changes the system will, by default, destroy the current activity and create a new one while preserving its state. In doing so, Android will reload the application's UI from the resources. Now imagine you wrote an application with a large bitmap that you don't want to load on every rotation. The easiest way to keep it around and not having to reload it on every rotation is to keep in a static field:
private static Drawable sBackground;
@Override
protected void onCreate(Bundle state) {
super.onCreate(state);
TextView label = new TextView(this);
label.setText("Leaks are bad");
if (sBackground == null) {
sBackground = getDrawable(R.drawable.large_bitmap);
}
label.setBackgroundDrawable(sBackground);
setContentView(label);
}
This code is very fast and also very wrong; it leaks the first activity created upon the first screen orientation change. When a Drawable
is attached to a view, the view is set as acallback
on the drawable. In the code snippet above, this means the drawable has a reference to the TextView
which itself has a reference to the activity (the Context
) which in turns has references to pretty much anything (depending on your code.)
This example is one of the simplest cases of leaking the Context
and you can see how we worked around it in the Home screen's source code (look for the unbindDrawables()
method) by setting the stored drawables' callbacks to null when the activity is destroyed. Interestingly enough, there are cases where you can create a chain of leaked contexts, and they are bad. They make you run out of memory rather quickly.
There are two easy ways to avoid context-related memory leaks. The most obvious one is to avoid escaping the context outside of its own scope. The example above showed the case of a static reference but inner classes and their implicit reference to the outer class can be equally dangerous. The second solution is to use the Application
context. This context will live as long as your application is alive and does not depend on the activities life cycle. If you plan on keeping long-lived objects that need a context, remember the application object. You can obtain it easily by calling Context.getApplicationContext()
or Activity.getApplication()
.
In summary, to avoid context-related memory leaks, remember the following:
- Do not keep long-lived references to a context-activity (a reference to an activity should have the same life cycle as the activity itself)
- Try using the context-application instead of a context-activity
- Avoid non-static inner classes in an activity if you don't control their life cycle, use a static inner class and make a weak reference to the activity inside. The solution to this issue is to use a static inner class with a
WeakReference
to the outer class, as done in ViewRoot and its W inner class for instance
- A garbage collector is not an insurance against memory leaks
分享到:
相关推荐
An Android console view, which allows you to log text using static calls, to easily debug your application, whilst avoiding memory leaks. Usage Include Console anywhere in your layout: then ...
Chapter 12, Audio in Game Development, explains how to add sound and music effects to games, and avoiding memory leaks while playing sounds. Chapter 13, Tips and Tricks, has some neat tips and tricks...
【避免垃圾邮件】 在互联网发展的历程中,从最初的物理学数据分享平台,到如今成为文化、教育,特别是商业生活的核心部分,网络已经变得无处不在。数以百万计的用户现在通过网页进行各种金融交易,包括购物、预订...
C++ Gotchas Avoiding Common Problems in Coding and Design 英文epub 本资源转载自网络,如有侵权,请联系上传者或csdn删除 本资源转载自网络,如有侵权,请联系上传者或csdn删除
气候变化研究中关于温度极端指数的处理方法Using a Monte Carlo simulation, it is demonstrated that percentile-based temperature indices computed for climate change detection and monitoring may contain ...
Android MVP Architecture A basic sample android application to understand MVP in a very simple way. Just clone, build, run ...avoiding Activity leaks by releasing the view when it's no longer needed ,B
Avoiding Read While Write Errors When In-Software Flash
在IT领域,尤其是在数据存储与保护的技术探讨中,《Avoiding the Disk Bottleneck in the Data Domain Deduplication File System》一文提供了深入的见解和技术解决方案,旨在优化基于磁盘的重复数据删除...
ARDUINO_OBSTACLE_AVOIDING_CAR 避开基于arduino的车辆的障碍在此存储库中,我仅给出了避开arduino基础车辆的障碍物的源代码。 您可以单击链接以获取源代码。 链接:
A note on cover-avoiding properties of finite groups,刘建军,郭秀云,A subgroup H of a group G is said to be a CAP*-subgroup of a group G if, for any non-Frattini chief factor K/L of G, we have HK=HL...
- **Memory Profiling**: Use memory profiling tools to identify memory leaks and excessive object creation. - **Memory Management**: Implement strategies to free up memory when it is no longer needed. ...
当构建使用动态VI的可执行文件时,必须确保在LabVIEW Application Builder规范的'always include'部分指定动态VI的名称。不这样做会导致问题,表现为LabVIEW应用程序将无法加载您的动态Vl,并将引发各种错误或导致...
自回避行走(Self-Avoiding Walk,简称SAW)是一种在数学、物理和化学领域广泛研究的统计力学模型。在该模型中,一个行走者在二维或三维空间中移动,但不能与其之前走过的路径重叠,即行走的每一步都不能与之前的...
是讲述安全编程的好书!!!
1Avoiding AVX-SSE Transition PenaltiesTransitioning between 256-bit Intel:registered: AVX instructions and legacy Intel:registered: SSE instructions within a program may cause performance penalties ...
An-OARSMan: An Obstacle-Avoiding Rectilinear Steiner Tree Algorithm with Good Length Performance,胡昱,经彤,Routing is one of the important steps in VLSI/ULSI physical design. The rectilinear ...
【Server Virtualization: 避免I/O陷阱】 在服务器虚拟化的过程中,企业通常能体验到应用程序部署的简化和整体服务器利用率的提升。然而,如果不考虑相应的存储I/O性能调整,这种快速整合可能会导致性能影响的隐患...
Topics covered include pointer arithmetic, dereferencing, and common pitfalls like dangling pointers and memory leaks. The chapter also provides practical tips for working with pointers, including ...