解决方案 »
- android桌面快捷方式,有没办法不重复创建进程?
- 谁能给我讲一下安卓到底是个什么东西
- 紧急求助:当执行View的onLongClick事件如何获得在屏幕上的坐标,谢谢了!
- 请教Log.wtf()方法有什么作用?
- android Tab TabHost 垂直显示
- socket客户端运行在真机上报:error opening trace file: No such file or directory (2) Refusin
- SQLite数据库操作,请问下这里面的movetoFirst到底有何用意?
- android panel
- android怎么通过jni调用C语言写得协议源码
- android imageview图片显示错乱 三星note3
- listview 动态添加
- 如何改变textview中文字的间距
Intent intent = new Intent(Activity1.this,Activity2.class);startActivity(intent);MainActivity.this.finish();System.gc();
不是调用finish就销毁了么?我读书少你别骗我
对 开始有一个说法说 要显示的把使用完的对象置空 于是在ondestroy中专门去
findViewById(xx) = null
这样去设置 可还是没用
可是我看了比较成熟的软件,如QQ、微博等,他们几乎都是没切换一个页面内存都会有明显的变化(增或减)
莫非他们是手动调用GC?可手动调GC增加GC压力岂不是一个饮鸩止渴的办法么?
private ImageView img;onCreate(Bundle xx) {
super.onCreate(xx);
img = new ImageView(this);
img.setImageResource(R.drawable.mypic);
setContentView(img, new LayoutParam(LayoutParam.MATCH_PARENT, LayoutParam.MATCH_PARENT); new Handler().post(
new Runnable() {
public void run() {
startActivity(new Intent(Activity1.this, Activity2.class));
finish();
}
}
}, 1000);
}onDestroy() {
super.onDestroy(); System.gc();
}
是不是改成这样会好点private ImageView img;
private Bitmap bmp;onCreate(Bundle xx) {
super.onCreate(xx);
img = new ImageView(this);
bmp = BitmapFactory.decodeResource(getResources(), R.drawable.xxx); //img.setImageResource(R.drawable.xxx);
img.setImageBitmap(bmp);
setContentView(img, new LayoutParam(LayoutParam.MATCH_PARENT, LayoutParam.MATCH_PARENT); new Handler().post(
new Runnable() {
public void run() {
startActivity(new Intent(Activity1.this, Activity2.class));
finish();
}
}
}, 1000);
}onDestroy() {
super.onDestroy(); //System.gc();
img = null;
bmp.recycle();
bmp = null;
}
是这样的吗?或者有这个必要吗?如果没必要,那么QQ那些软件为何切换的时候内存会明显变化呢?
问题描述:
我现在做的一个页面,就一个简单的ListView,只是数据长度可能比较长,极端情况下可能会像微博那样吧(无限制的),当然是做了分页的,不论怎么滚动虽然不会OOM,但是一旦数据多了系统一直处于随时会触发GC的状态,首先反应出来的情况就是卡,其次是跳转到其他页面后,在这种情况下,很容易OOM,也就是系统不稳定解决办法:
于是我专门去看了微博的内存管理:
1、我一直滑动,一直加载数据,发现内存到达某一阀值的时候会出现减的情况,猜想他可能回收了不可见部分的Bitmap吧,但是怎么做呢?ListView的回收机制自动回收的吗?如果不是那触发回收的时候如何设置Listener,然后手动回收Bitmap呢?
2、从列表页跳转到微博详情的时候,内存也会减小,这个时候的回收策略又该怎样来呢?回收完所有不可见区域的Bitmap吗?那问题同上,如何来进行呢?好了,这其实才我真正的问题,本以为解决前面那个问题,这个问题就迎刃而解了,可没我想的那么简单,所以还是贴直接遇到的问题出来吧!
首先两个Activity:MainActivity、MainActivity1MainActivity: protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
layout = new LinearLayout(this);
Button btn = new Button(this);
img = new ImageView(this);
btn.setText("activity0");
img.setScaleType(ScaleType.CENTER_CROP);
bmp = Bitmap.createBitmap(5000, 5000, Bitmap.Config.ARGB_8888);
img.setImageBitmap(bmp);
//开始为了验证是不是直接设置资源和设置Bitmap不一样,可测试后证明是一样的
//img.setImageResource(R.drawable.aa);
layout.setOrientation(LinearLayout.VERTICAL);
layout.addView(btn, new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
layout.addView(img, new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
setContentView(layout, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
startActivity(new Intent(MainActivity.this, MainActivity1.class));
//在MainActivity2中则是,除此之外都一样
//startActivity(new Intent(MainActivity2.this, MainActivity3.class));
finish();
/*
* 执行回收
* 在这里调用的原因参见onDestroy中的注释
*/
doRecycle();
}
});
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
/*
* 是不是很奇怪为什么不在这里调用?
* 在没有执行“img.setImageBitmap(bmp);”这句代码(也就是注释起来)的时候
* 在“finish();”的后面调用能够起到回收内存的作用,怎么判断?看log,通过emmagee,通过第三方清理软件查看
* 但是
* 在执行了“img.setImageBitmap(bmp);”的时候,就不论在哪调用都不会起作用了
*/
//doRecycle();
}
private void doRecycle() {
//没看过源码,但是怕引用链的开头就是从这里开始,故覆盖了一个
setContentView(new View(MainActivity.this));
//也是为了切断引用链
layout.removeAllViews();
layout = null;
//同上,也有个说法直接设置null,但亲测都一样
img.setImageBitmap(Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_4444));
img = null;
//不用多说吧
bmp.recycle();
bmp = null;
//等不了这慢吞吞的GC大哥了,手动通知他
System.gc();
}
MainActivity1:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button btn = new Button(this);
btn.setText("activity1");
//在MainActivity3中则是,除标注了的其他都一样
btn.setText("activity3");
setContentView(btn, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
startActivity(new Intent(MainActivity1.this, MainActivity2.class));
//在MainActivity3中则是,除标注了的其他都一样
//startActivity(new Intent(MainActivity3.this, MainActivity.class));
finish();
System.gc();
}
});
}Log信息
1、在MainActivity中,点击按钮跳转到MainActivity1的时候
GC_EXPLICIT freed 107K, 1% free 101517K/101960K, paused 4ms+3ms, total 27ms
2、手动点击GC的时候GC_EXPLICIT freed 97757K, 97% free 3995K/102024K, paused 4ms+5ms, total 47ms
GC_EXPLICIT freed 118K, 97% free 3877K/102024K, paused 4ms+4ms, total 45ms
GC_EXPLICIT freed <1K, 97% free 3877K/102024K, paused 3ms+4ms, total 37ms3、在MainActivity1中,点击按钮跳转到MainActivity的时候GC_CONCURRENT freed 164K, 96% free 4127K/102024K, paused 10ms+10ms, total 38ms
GC_FOR_ALLOC freed 12K, 96% free 4135K/102024K, paused 17ms, total 17ms
Forcing collection of SoftReferences for 100000016-byte allocation
GC_BEFORE_OOM freed 0K, 96% free 4135K/102024K, paused 32ms, total 32ms
Out of memory on a 100000016-byte allocation.
为什么第一次跳转的时候,GC没有释放掉堆内存,而又为什么recycle之后,不论怎么样GC,不论是哪种类型的GC都不能释放掉Native的内存?
(心想:怎么老犯这种很二的错)
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button btn = new Button(this);
btn.setText("activity1");
setContentView(btn, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
startActivity(new Intent(MainActivity1.this, MainActivity.class));
finish();
System.gc();
}
});
}
谢谢 可是我用模拟器运行也是这样的
而且我的手机 看别人的应用就能回收(QQ等)好吧,我暂时也找到代替方法了,就采用那些所谓“内存管理”软件的方法——杀进程
这样能立即回收,但是,切换activity的时候会闪烁一下无解