内存溢出的解决方案

简介:       最近做新闻客户端的时候在加载ListView的大图时会发生内存溢出的问题。内存溢出(OOM)。为了便于理解,我们不妨打个比方。缓冲区溢出好比是将十磅的糖放进一个只能装五磅的容器里。一旦该容器放满了,余下的部分就溢出在柜台和地板上,弄得一团糟。由于计算机程序的编写者写了一些编码,但是这些编码没有对目的区域或缓冲区——五磅的容器——做适当的检查,看它们是否够大,能否完全装入新的


      最近做新闻客户端的时候在加载ListView的大图时会发生内存溢出的问题。内存溢出(OOM)。为了便于理解,我们不妨打个比方。缓冲区溢出好比是将十磅的糖放进一个只能装五磅的容器里。一旦该容器放满了,余下的部分就溢出在柜台和地板上,弄得一团糟。由于计算机程序的编写者写了一些编码,但是这些编码没有对目的区域或缓冲区——五磅的容器——做适当的检查,看它们是否够大,能否完全装入新的内容——十磅的糖,结果可能造成缓冲区溢出的产生。如果打算被放进新地方的数据不适合,溢得到处都是,该数据也会制造很多麻烦。但是,如果缓冲区仅仅溢出,这只是一个问题。到此时为止,它还没有破坏性。当糖溢出时,柜台被盖住。可以把糖擦掉或用吸尘器吸走,还柜台本来面貌。与之相对的是,当缓冲区溢出时,过剩的信息覆盖的是计算机内存中以前的内容。除非这些被覆盖的内容被保存或能够恢复,否则就会永远丢失。

       首先想到的是三级缓存,从服务器下载下来的图片经过网络缓存,但是这种方法不优先加载, 速度慢,浪费流量。然后是本地缓存,次优先加载, 速度快;最后最好的是内存缓存,优先加载, 速度最快。我们都知道Android默认给每个app只分配16M的内存,所以用软引用 SoftReference   在内存不够时,垃圾回收器会考虑回收。但是在安卓2.3+,系统会优先将SoftReference的对象提前回收掉, 即使内存够用。所以谷歌官方建议用LruCache。least recentlly use 最少最近使用算法

会将内存控制在一定的大小内, 超出最大值时会自动回收, 这个最大值开发者自己定。其实LruCache就是用了很多的HashMap,三百多行的代码。


/**
 * 内存缓存 
 */
public class MemoryCacheUtils {

	// private HashMap<String, SoftReference<Bitmap>> mMemoryCache = new
	// HashMap<String, SoftReference<Bitmap>>();
	private LruCache<String, Bitmap> mMemoryCache;

	public MemoryCacheUtils() {
		long maxMemory = Runtime.getRuntime().maxMemory() / 8;// 模拟器默认是16M
		mMemoryCache = new LruCache<String, Bitmap>((int) maxMemory) {
			@Override
			protected int sizeOf(String key, Bitmap value) {
				int byteCount = value.getRowBytes() * value.getHeight();// 获取图片占用内存大小
				return byteCount;
			}
		};
	}

	/**
	 * 从内存读
	 * 
	 * @param url
	 */
	public Bitmap getBitmapFromMemory(String url) {
		// SoftReference<Bitmap> softReference = mMemoryCache.get(url);
		// if (softReference != null) {
		// Bitmap bitmap = softReference.get();
		// return bitmap;
		// }
		return mMemoryCache.get(url);
	}

	/**
	 * 写内存
	 * 
	 * @param url
	 * @param bitmap
	 */
	public void setBitmapToMemory(String url, Bitmap bitmap) {
		// SoftReference<Bitmap> softReference = new
		// SoftReference<Bitmap>(bitmap);
		// mMemoryCache.put(url, softReference);
		mMemoryCache.put(url, bitmap);
	}
}
java中的引用

- 强引用 垃圾回收器不会回收, java默认引用都是强引用
- 软引用 SoftReference   在内存不够时,垃圾回收器会考虑回收
- 弱引用 WeakReference  在内存不够时,垃圾回收器会优先回收
- 虚引用 PhantomReference  在内存不够时,垃圾回收器最优先回收

</pre><pre name="code" class="java">为进一步优化,我们还可以考虑图片压缩技术:

//图片压缩处理
				BitmapFactory.Options option = new BitmapFactory.Options();
				option.inSampleSize = 2;//宽高都压缩为原来的二分之一, 此参数需要根据图片要展示的大小来确定
				option.inPreferredConfig = Bitmap.Config.RGB_565;//设置图片格式


当然,如果我们用BitmapUtils也是可以的。


目录
相关文章
|
8月前
|
运维 监控 Java
内存溢出+CPU占用过高:问题排查+解决方案+复盘(超详细分析教程)
全网最全的内存溢出CPU占用过高排查文章,包含:问题出现现象+临时解决方案+复现问题+定位问题发生原因+优化代码+优化后进行压测,上线+复盘
1372 5
|
2月前
|
存储 监控 Java
JVM内存泄漏的分析与解决方案
JVM内存泄漏的分析与解决方案
|
数据库
mongo占用内存过大解决方案
自己有一个测试用的服务器,配置很低。年前出现几次问题,重启后就好了也就没注意。后来越来越频繁就调查了一下,发现重启后内存就一直增长直到接近100%。使用ps aux查看cpu和内存使用情况,发现mongo占用了大部分的内存,这是什么情况?
677 0
|
5月前
|
Arthas Java 测试技术
微服务轮子项目(49) -常见JVM内存错误及解决方案
微服务轮子项目(49) -常见JVM内存错误及解决方案
66 0
|
5月前
|
存储 数据库 C语言
Hawkeyes: x86软件迁移Arm的弱内存序问题解决方案
本文介绍了x86软件迁移到Arm过程中可能遇到的弱内存序问题的解决方案,解析了弱内存序问题的根因,介绍了Hawkeyes的架构和实现原理。欢迎有需求的团队发送邮件咨询
596 0
|
8月前
|
存储 监控 NoSQL
深入探究Redis:内存模型、哨兵选举算法与脑裂解决方案
深入探究Redis:内存模型、哨兵选举算法与脑裂解决方案
389 1
|
9月前
|
前端开发 API PHP
php内存溢出:Allowed memory size of 1342bytes exhausted (tried to allocate 8192 bytes)本地配置和宝塔配置解决方案
php内存溢出:Allowed memory size of 1342bytes exhausted (tried to allocate 8192 bytes)本地配置和宝塔配置解决方案
83 0
|
9月前
|
算法 Java Android开发
JVM内存溢出及其解决方案
Java虚拟机(JVM)是执行Java程序的核心环境,它管理着应用程序的内存分配和回收。然而,在某些情况下,应用程序可能会遇到内存溢出的问题,即JVM无法为应用程序分配足够的内存空间。本文将探讨JVM内存溢出的原因以及解决方案,帮助开发人员更好地理解和处理这一问题。
191 0
|
12月前
|
消息中间件 存储 JavaScript
ThreadLocal 搭配线程池使用造成内存泄漏的原因和解决方案
ThreadLocal 搭配线程池使用造成内存泄漏的原因和解决方案
PHP内存泄漏问题的原因是什么?解决方案是什么?
PHP内存泄漏问题的原因是什么?解决方案是什么?
545 0