zoukankan      html  css  js  c++  java
  • Android OutOfMemoryError的理解

    最近写了个测试demo调试网络优化,发现下载20M的文件时我直接申请了20M的空间,然后就OOM导致crash了~~

    典型的错误信息如下:

     OutOfMemoryError:Out of memory: Heap Size=33887KB, Allocated=22009KB, Limit=49152KB

    1,百度一下,有人说是资源没释放内存泄露导致,这种情况只能自己去优化内存管理了,我这个明显不是,我就是要用这么多!!

    2,看到有个小哥做了处理能加载5M*20张图片一点事没有,纯代码分享(拍砖表情在此!!链接在次

    3,这个小哥比较霸气(链接在此),提出的方法:

    1. 修改内存大小限制定义 (但是: 函数setMinimumHeapSize其实只是改变了堆的下限值,它可以防止过于频繁的堆内存分配,当设置最小堆内存大小超过上限值(Max Heap Size)时仍然采用堆的上限值,对于内存不足没什么作用。)
      private final static int CWJ_HEAP_SIZE = 6* 1024* 1024 ;         
      VMRuntime.getRuntime().setMinimumHeapSize(CWJ_HEAP_SIZE); //设置最小heap内存为6MB大小。      
      private final static int CWJ_HEAP_SIZE = 6* 1024* 1024 ; 
      VMRuntime.getRuntime().setMinimumHeapSize(CWJ_HEAP_SIZE); //设置最小heap内存为6MB大小。
    2. 手动干涉GC 
      private final static floatTARGET_HEAP_UTILIZATION = 0.75f;        
      private final static floatTARGET_HEAP_UTILIZATION = 0.75f;
      
      // OnCreate
      VMRuntime.getRuntime().setTargetHeapUtilization(TARGET_HEAP_UTILIZATION);        
      VMRuntime.getRuntime().setTargetHeapUtilization(TARGET_HEAP_UTILIZATION); 
    3. NDK

    4,这个小哥总结的很好(链接在此

    1. 缓存图像到内存,采用软引用缓存到内存,而不是在每次使用的时候都从新加载到内存;
    2. 调整图像大小,手机屏幕尺寸有限,分配给图像的显示区域本身就更小,有时图像大小可以做适当调整;
    3. 采用低内存占用量的编码方式,比如Bitmap.Config.ARGB_4444比Bitmap.Config.ARGB_8888更省内存;
    4. 及时回收图像,如果引用了大量Bitmap对象,而应用又不需要同时显示所有图片,可以将暂时用不到的Bitmap对象及时回收掉;
    5. 自定义堆内存分配大小,优化Dalvik虚拟机的堆内存分配;

    5,这个小哥说的更清楚一些(链接在此

    总结:

    其实我这里的问题主要是EntityUtils.toString的时候一下输出的太大了。

    参考 https://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/gson/JsonStreamParser.html ,总的来说,不能一下子把大量数据载入内存!!

    其实可以自己参考EntityUtils.toString的写法自己实现一个不要一下子全拼到String里的方法:

     1         public long readResponse(HttpEntity entity) throws IOException{
     2             long responseLength = 0;
     3 
     4             int i = (int)entity.getContentLength();
     5             if(i < 0) {
     6                 i = 4096;
     7             }
     8 
     9             InputStream instream = entity.getContent();
    10             InputStreamReader reader = new InputStreamReader(instream);
    11 //            CharArrayBuffer buffer = new CharArrayBuffer(i);
    12 
    13             try {
    14                 char[] tmp = new char[1024];
    15 
    16                 int l;
    17                 while((l = reader.read(tmp)) != -1) {
    18 //                    buffer.append(tmp, 0, l);
    19                     responseLength += tmp.length;
    20                 }
    21             } finally {
    22                 reader.close();
    23             }
    24             return responseLength;
    25         }
  • 相关阅读:
    什么时候用resultMap,什么时候用resultType?
    Cannot create PoolableConnectionFactory解决思路
    去除list集合中重复项的几种方法-转载
    ORA-02298 定位问题
    命令行退出MySQL和登录MySQL
    CX4-480服务器数据恢复过程(服务器数据恢复通用方法)
    也谈腾讯云的静默损坏
    raid5阵列两块硬盘离线怎么解决
    服务器卷删除初检报告/数据恢复成功率分析
    服务器两块硬盘离线如何恢复数据
  • 原文地址:https://www.cnblogs.com/icxy/p/5408666.html
Copyright © 2011-2022 走看看