内存溢出解决方案
1.内存溢出(OOM)是指应用系统中存在无法回收的内存或使用的内存过多,最终使得程序运行要用到的内存大于虚拟机能提供的最大内存。为了解决Java中内存溢出问题,
我们首先必须了解Java是如何管理内存的。Java的内存管理就 是对象的分配和释放问题。在Java中,内存的分配是由程序完成的,而内存的释放是由垃圾收集器(GarbageCollection,GC)完成的,
程 序员不需要通过调用GC函数来释放内存,因为不同的JVM实现者可能使用不同的算法管理GC,有的是内存使用到达一定程度时,GC才开始工作,也有定时执 行的,有的是中断式执行GC。
但GC只能回收无用并且不再被其它对象引用的那些对象所占用的空间。Java的内存垃圾回收机制是从程序的主要运行对象开始检查引用链,当遍历一遍后发现没有被引用的孤立对象就作为垃圾回收。
引起内存溢出的原因有很多种,常见的有以下几种:
内存中加载的数据量过于庞大,如一次从数据库取出过多数据;
集合类中有对对象的引用,使用完后未清空,使得JVM不能回收;
代码中存在死循环或循环产生过多重复的对象实体;
启动参数设定的过小;
2.内存溢出解决方案
- Android默认给每个app只分配16M的内存
方法1:等比例缩小图片
1 /** 2 * 3 * 下载图片 4 * @return 5 */ 6 private Bitmap downloadBitmap(String url){ 7 HttpURLConnection conn=null; 8 try { 9 conn=(HttpURLConnection) new URL(url) 10 .openConnection(); 11 12 conn.setConnectTimeout(5000); 13 conn.setReadTimeout(5000); 14 conn.setRequestMethod("GET"); 15 conn.connect(); 16 17 int responseCode = conn.getResponseCode();//响应码 18 19 if(responseCode==200){//表示成功连接 20 InputStream inputStream = conn.getInputStream(); 21 22 //图片的压缩设置 23 BitmapFactory.Options option=new Options(); 24 option.inSampleSize=2;//表示将图片压缩原来的二分之一,需要根据图片的大小来计算出压缩值的大小 25 option.inPreferredConfig=Bitmap.Config.RGB_565;//通过设置图片的格式即像素大小来进行图片的压缩 26 27 Bitmap bitmap = BitmapFactory.decodeStream(inputStream,null,option); 28 return bitmap; 29 } 30 31 } catch (IOException e) { 32 33 e.printStackTrace(); 34 } 35 finally{ 36 conn.disconnect(); 37 } 38 return null; 39 40 }
方法2. java中的引用,对图片采用软引用,及时地进行recyle()操作
- 强引用 垃圾回收器不会回收, java默认引用都是强引用
- 软引用 SoftReference 在内存不够时,垃圾回收器会考虑回收
- 弱引用 WeakReference 在内存不够时,垃圾回收器会优先回收
- 虚引用 PhantomReference 在内存不够时,垃圾回收器最优先回收
注意: Android2.3+, 系统会优先将SoftReference的对象提前回收掉, 即使内存够用
1 /** 2 * 3 * 内存缓存 4 * @author admin 5 * 6 */ 7 public class MemoryCacheUtils { 8 9 private HashMap<String, SoftReference<Bitmap>> hashlist=new HashMap<String, SoftReference<Bitmap>>(); 10 11 12 /** 13 * 14 * 从内存中读 15 * @param url 16 * @return 17 */ 18 public Bitmap getBitmapFrommemory(String url){ 19 SoftReference<Bitmap> soft= hashlist.get(url); 20 if(soft!=null){ 21 Bitmap bitmap = soft.get(); 22 return bitmap; 23 } 24 return null; 25 26 27 } 28 29 30 /** 31 * 32 * 写入内存 33 * @param url 34 * @param bitmap 35 */ 36 public void setBitmapTomemory(String url,Bitmap bitmap){ 37 SoftReference<Bitmap> softReference = new SoftReference<Bitmap>(bitmap); 38 if(softReference!=null){ 39 hashlist.put(url, softReference); 40 } 41 } 42 }
方法3.LruCache
## LruCache ##
least recentlly use 最少最近使用算法
会将内存控制在一定的大小内, 超出最大值时会自动回收, 这个最大值开发者自己定
1 /** 2 * 3 * 内存缓存 4 * @author admin 5 * 6 */ 7 public class MemoryCacheUtils { 8 9 // private HashMap<String, SoftReference<Bitmap>> hashlist=new HashMap<String, SoftReference<Bitmap>>(); 10 11 private LruCache<String, Bitmap> lrucache; 12 public MemoryCacheUtils() { 13 long maxMemory = Runtime.getRuntime().maxMemory()/8;//设置允许占用最大内存 14 lrucache=new LruCache<String, Bitmap>((int) maxMemory){ 15 @Override 16 protected int sizeOf(String key, Bitmap value) { 17 int bytecount=value.getRowBytes() * value.getHeight(); 18 return bytecount; 19 } 20 21 }; 22 } 23 /** 24 * 25 * 从内存中读 26 * @param url 27 * @return 28 */ 29 public Bitmap getBitmapFrommemory(String url){ 30 // SoftReference<Bitmap> soft= hashlist.get(url); 31 // if(soft!=null){ 32 // Bitmap bitmap = soft.get(); 33 // return bitmap; 34 // } 35 Bitmap bitmap = lrucache.get(url); 36 return bitmap; 37 38 39 } 40 41 42 /** 43 * 44 * 写入内存 45 * @param url 46 * @param bitmap 47 */ 48 public void setBitmapTomemory(String url,Bitmap bitmap){ 49 // SoftReference<Bitmap> softReference = new SoftReference<Bitmap>(bitmap); 50 // if(softReference!=null){ 51 // hashlist.put(url, softReference); 52 // } 53 lrucache.put(url, bitmap); 54 } 55 }