标签:function memory 优点 get deb 保存 抽取 数据 ash
Android 平台最吸引开发者的一个特性:有垃圾回收机制,无需手动管理内存,Android 系统会自动跟踪所有的对象,并释放那些不再被使用的对象
Young Generation 新生代
Minor GC 同样会检查survivor区中存活下来的对象,并把他们转移到另一个survivor区,这样在一段时间内,总会有一个空的survivor区
Old Generation 老生代
满了进行Major GC(较重GC)
Permanent Generation 永久代
存放方法区,方法区中有,要加载的类信息、静态变量、final类型的常量、属性和方法信息
在整个Android开发过程中,内存泄漏是导致OOM(Out Of Memory内存溢出)的一个重要因素
原因:内存抖动是因为应用程序在短时间内创建大量的对象,又被马上释放。
引用
dependencies {
debugCompile ‘com.squareup.leakcanary:leakcanary-android:1.3‘
releaseCompile ‘com.squareup.leakcanary:leakcanary-android-no-op:1.3‘
}
使用
// 内存泄漏检测
private RefWatcher refWatcher;
public static RefWatcher getRefWatcher(Context context) {
TTApplication application = (TTApplication) context.getApplicationContext();
return application.refWatcher;
}
@Override
public void onCreate() {
super.onCreate();
refWatcher = LeakCanary.install(this); // 检测
}
public void onDestroy() {
RefWatcher refWatcher = TTApplication.getRefWatcher(getActivity());
refWatcher.watch(this); //内存泄露检测
}</code>
将Context对象保存在单例模式中,instance对象本身持有一个Context对象的引用,活动即时被销毁也不能被回收,因为静态变量一直持有它的引用
public class AppManager {
private static AppManager instance;
private Context context;
private AppManager(Context context) {
this.context = context;
}
public static AppManager getInstance(Context context) {
if (instance != null) {
instance = new AppManager(context);
}
return instance;
}
}
可以改为
public class AppManager {
private static AppManager instance;
private Context context;
private AppManager(Context context) {
// 使用Application的Context(也可以用自定义的Application)
this.context = context.getApplicationContext();
}
public static AppManager getInstance(Context context) {
if (instance != null) {
instance = new AppManager(context);
}
return instance;
}
}
静态的sResource在创建时会间接持有一个MainActivity实例的引用,导致MainActivity无法被回收
public class MainActivity extends Activity {
private static TestResource sResource = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (sResource == null) {
sResource = new TestResource();
}
// ...
}
// 非静态内部类
class TestResource {
// ...
}
}
将该内部类设为静态内部类或将该内部类抽取出来封装成一个单例
如果用到Context就使用Application的Context
但是Dialog不能使用Application和Service的Context
当创建匿名对象时,该对象会间接持有外部类实例的一个引用,mHandler对象本身会持有MainActivity的引用,导致MainActivity销毁后无法即时被回收
public class MainActivity extends Activity {
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
loadData();
}
private void loadData() {
// ...request
Message message = Message.obtain();
mHandler.sendMessage(message);
}
}
在Activity中避免使用非静态内部类,比如将Handler声明为静态的,这样Handler的存活时间就与Activity无关了
同时引入弱引用的方式引入Activity,避免将Activity作为Context传入
使用前判空
public class MainActivity extends Activity {
private static class MyHandler extends Handler {
private final WeakReference<MainActivity> mActivity;
private MyHandler(MainActivity activity){
mActivity = new WeakReference<MainActivity>(activity);
}
@Override
public void handleMessage(Message msg) {
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
loadData();
}
private void loadData() {
// ...request
Message message = Message.obtain();
mHandler.sendMessage(message);
}
}
使用更轻量的数据结构(SpareArray代替HashMap)
避免在onDraw方法中创建对象
对象池(Message.obtain())
LRUCache
Bitmap内存复用,压缩(inSampleSize,inBitmap)
StringBuilder
标签:function memory 优点 get deb 保存 抽取 数据 ash
原文地址:http://www.cnblogs.com/benchao/p/6032222.html