zoukankan      html  css  js  c++  java
  • 内存溢出解决方案

    内存溢出解决方案

    1.内存溢出(OOM)是指应用系统中存在无法回收的内存或使用的内存过多,最终使得程序运行要用到的内存大于虚拟机能提供的最大内存。为了解决Java中内存溢出问题,

    我们首先必须了解Java是如何管理内存的。Java的内存管理就 是对象的分配和释放问题。在Java中,内存的分配是由程序完成的,而内存的释放是由垃圾收集器(GarbageCollection,GC)完成的,

    程 序员不需要通过调用GC函数来释放内存,因为不同的JVM实现者可能使用不同的算法管理GC,有的是内存使用到达一定程度时,GC才开始工作,也有定时执 行的,有的是中断式执行GC。

    但GC只能回收无用并且不再被其它对象引用的那些对象所占用的空间。Java的内存垃圾回收机制是从程序的主要运行对象开始检查引用链,当遍历一遍后发现没有被引用的孤立对象就作为垃圾回收。

    引起内存溢出的原因有很多种,常见的有以下几种:

     内存中加载的数据量过于庞大,如一次从数据库取出过多数据;

     集合类中有对对象的引用,使用完后未清空,使得JVM不能回收;

     代码中存在死循环或循环产生过多重复的对象实体;

     使用的第三方软件中的BUG

     启动参数设定的过小;

    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 }

     

     

     

  • 相关阅读:
    Oracle数据导出到MySql
    ORA04031 shared_pool 不能分配足够内存或磁盘碎片
    IDEA那些好用的插件
    MySQL基础篇增删改查
    SpringBoot项目部署在阿里云
    三、Mybatis相应API
    chrome的书签备份
    redis踩坑
    四、Mybatis的Dao层实现
    MySQL基础篇函数
  • 原文地址:https://www.cnblogs.com/wangying222/p/5272073.html
Copyright © 2011-2022 走看看