0
点赞
收藏
分享

微信扫一扫

【达内课程】音乐播放器4.0(Android中的GC垃圾回收机制、图片优化)


文章目录

  • ​​GC 垃圾回收机制​​
  • ​​Java 中的引用​​

GC 垃圾回收机制

【达内课程】音乐播放器4.0(Android中的GC垃圾回收机制、图片优化)_软引用
当main()方法执行完,main()方法中的局部变量都会弹栈,从栈当中销毁
当左侧栈中的e2和e销毁后,右侧中的两个对象就是垃圾
java底层有一种GC垃圾回收机制,在java程序运行时,GC线程会不断找寻垃圾,是的话会清除掉

【GC垃圾回收机制】
垃圾回收是一种自动的存储管理机制。 当一些被占用的内存不再需要时,就应该予以释放,以让出空间,这种存储资源管理,称为垃圾回收(Garbage Collection)。

Java 语言提供了自动的 GC 机制,系统会经常检查内存,采用对象引用计数的方式,将引用次数为 0 的对象回收。这样可以防止两个危险:(1)防止无用对象占用内存资源 (2)防止有用对象被释放,引起内存非法引用。

当 Java 程序在运行时,GC垃圾回收机制也将会在适当的时候执行,GC将会把内存中的垃圾对象所占用的内存自动释放掉

【什么时候将会执行垃圾回收机制】
(1)应用进程空闲的时候,GC会回收空闲进程的内存资源。
(2)应用进程繁忙的时候,当需要的内存资源不足的时候, GC会强制执行回收优先级比较低的进程资源,如果还是不足,则再回收两次,还是不足则会报OOM

【GC的特点】
GC 在执行的过程中,所有线程暂停。等 GC 执行完毕后,所有线程再继续执行。
所以我们需要减少 GC 的执行频率

当我们点击模拟机的返回键时,发生了什么
【达内课程】音乐播放器4.0(Android中的GC垃圾回收机制、图片优化)_垃圾回收机制_02
当GC想回收Activity时,发现被Adapter引用
【达内课程】音乐播放器4.0(Android中的GC垃圾回收机制、图片优化)_GC_03
当GC想回收Adapter时,发现有一条阻塞的线程
【达内课程】音乐播放器4.0(Android中的GC垃圾回收机制、图片优化)_软引用_04
当我们点击手机的返回键时,Activity并不会被销毁,当再打开时,我们观察运行的线程,会增加一条。返回再打开,又会增加线程…
​​​如何查看工作的线程​​​【达内课程】音乐播放器4.0(Android中的GC垃圾回收机制、图片优化)_垃圾回收机制_05
【达内课程】音乐播放器4.0(Android中的GC垃圾回收机制、图片优化)_java_06
解决办法如下:
在NewMusicListFragment中重写onDestroy()方法

@Override
public void onDestroy() {
//把adapter中的线程销毁
adapter.stopThread();
super.onDestroy();
}

MusicAdapter中增加stopThread()方法

public void stopThread() {
//isLoop为false,循环停止
isLoop = false;
//当我们按返回键时,线程在wait(),应先唤醒
synchronized (workThread) {
workThread.notify();
}
}

重复刚才操作,不会新增线程
【达内课程】音乐播放器4.0(Android中的GC垃圾回收机制、图片优化)_软引用_07

​​android 垃圾回收机制​​

Java 中的引用

1、强引用 Strong Reference
就算出现 OOM,GC 也不会销毁任何强引用。
2、软引用 Soft Reference
当 Java 所管理的内存趋于阈值时,GC 将会销毁部分软引用释放内存
3、弱引用 Weak Reference
引用强度弱于软引用
4、虚引用…

如何使用软引用实现内存缓存

HashMap<path,SoftReference<Bitmap>> cache;
存:
cache.put(url,new SoftReference(bitmap));

SoftReference ref = cache.get(url);
if(ref!=null){
Bitmap bitmap = ref.get();
if(bitmap != null){
//设置 ImageView
}
}

修改 MusicAdapter

/**
* 音乐列表适配器
*/
public class MusicAdapter extends BaseAdapter {
......
private ListView listView;
private HashMap<String,SoftReference<Bitmap>> cache = new HashMap<>();
......

/**
* 通过url地址 发送http请求 获取图片
* @param url
* @return
*/
private Bitmap loadBitmap(String url){
try {
InputStream is = HttpUtils.getInputStream(url);
//执行压缩算法,获取合适尺寸的图片
Bitmap bitmap = BitmapUtils.loadBitmap(is,50,50);
//Bitmap bitmap = BitmapFactory.decodeStream(is);
//把bitmap放入内存缓存
cache.put(url,new SoftReference<Bitmap>(bitmap));
return bitmap;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
......

@Override
public View getView(int i, View view, ViewGroup viewGroup) {
ViewHolder holder = null;
......
//给holder.imgPic设置图片
//先去内存缓存中看有没有
SoftReference<Bitmap> ref = cache.get(music.getPic_small());
if(ref!=null){//以前存过
Bitmap bitmap = ref.get();
if(bitmap!=null){//以前存的还没有被清掉
holder.imgPic.setImageBitmap(bitmap);
return view;
}
}
//向任务集合中一个图片下载任务
holder.imgPic.setTag(music.getPic_small());
......
return view;
}
......
}

举报

相关推荐

0 条评论