android 内存溢出
参考:http://1002878825-qq-com.iteye.com/blog/1735356
出现情况:
1.使用大图片,没有及时recycle。
4.0后bitmap.option 中有 inPurgeable 内存不足可以回收,之前版本必须自己回收
解决:1.option 减小图片加载 2.使用软引用,及时recycle
2.listview的convertView 以及未用holder机制的运用
原因:contentView 系统已经缓存
解决:1.holder 判断 contentView是会否为空
2.提高顺滑度listview lazy loading data ----- 参考资料:api demo list 13 滑动时不赋值
public class List13 extends ListActivity implements ListView.OnScrollListener { private TextView mStatus; private boolean mBusy = false; /** * Will not bind views while the list is scrolling * */ private class SlowAdapter extends BaseAdapter { private LayoutInflater mInflater; public SlowAdapter(Context context) { mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); } /** * The number of items in the list is determined by the number of speeches * in our array. * * @see android.widget.ListAdapter#getCount() */ public int getCount() { return mStrings.length; } /** * Since the data comes from an array, just returning the index is * sufficent to get at the data. If we were using a more complex data * structure, we would return whatever object represents one row in the * list. * * @see android.widget.ListAdapter#getItem(int) */ public Object getItem(int position) { return position; } /** * Use the array index as a unique id. * * @see android.widget.ListAdapter#getItemId(int) */ public long getItemId(int position) { return position; } /** * Make a view to hold each row. * * @see android.widget.ListAdapter#getView(int, android.view.View, * android.view.ViewGroup) */ public View getView(int position, View convertView, ViewGroup parent) { TextView text; if (convertView == null) { text = (TextView)mInflater.inflate(android.R.layout.simple_list_item_1, parent, false); } else { text = (TextView)convertView; } if (!mBusy) { text.setText(mStrings[position]); // Null tag means the view has the correct data text.setTag(null); } else { text.setText("Loading..."); // Non-null tag means the view still needs to load it's data text.setTag(this); } return text; } } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.list_13); mStatus = (TextView) findViewById(R.id.status); mStatus.setText("Idle"); // Use an existing ListAdapter that will map an array // of strings to TextViews setListAdapter(new SlowAdapter(this)); getListView().setOnScrollListener(this); } public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { } public void onScrollStateChanged(AbsListView view, int scrollState) { switch (scrollState) { case OnScrollListener.SCROLL_STATE_IDLE: mBusy = false; int first = view.getFirstVisiblePosition(); int count = view.getChildCount(); for (int i=0; i<count; i++) { TextView t = (TextView)view.getChildAt(i); if (t.getTag() != null) { t.setText(mStrings[first + i]); t.setTag(null); } } mStatus.setText("Idle"); break; case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL: mBusy = true; mStatus.setText("Touch scroll"); break; case OnScrollListener.SCROLL_STATE_FLING: mBusy = true; mStatus.setText("Fling"); break; } }
3.单个页面,横竖屏切换N次后
解决:1.去除xml中相关设置,改在程序中设置背景图(放在onCreate()方法中):
2. 跟上面方法相似,直接把xml配置文件加载成view 再放到一个容器里,然后直接调用 this.setContentView(View view)方法,避免xml的重复加载
3.Activity中添加了 android:configChanges属性,目的是当所指定属性(Configuration Changes)发生改变时,通知程序调用 onConfigurationChanged()函数
解决通用方法:
1.SoftReference 和 WeakReference的使用
2.压缩图片参考解决bitmap章节
3.修改虚拟机参数 VMRuntime.getRuntime().setTargetHeapUtilization(0.75);
4.不要为Context长期保存引用(生命周期结束处理掉)
5.尽量用ApplicationContext
6.垃圾回收器并不保证能准确回收内存,这样在使用自己需要的内容时,主要生命周期和及时释放掉不需要的对象。尽量在Activity的生命周期结束时,在onDestroy中把我们做引用的其他对象做释放,比如:cursor.close()。