关于大多数程序猿(码农)来讲,一提到内存优化一定都是比较头大,我也不破例,但是由于我们这个项目就我一我的作,出疑问了也没有大牛处理,因此只能是自个硬着头皮上了。 服务器
言归正传,先告知一下工做的原因。楼主是作网盘项目的,从从未触摸过度块上载、断点续传(曾经一听断点续传也是头大)到牵强把分块上载下载作完,也是阅历了不少苦楚的,但是,有一个工做一贯是我不肯供认不想面临但却恰恰存在的疑问,那便是下载的时分界面十分卡顿!是十分卡,不是通常的卡!小文件还好,感受不出来,但是一超越100M就会十分卡甚至是ANR。没办法了,尽管我一贯想躲避,但是这个总需求处理,只能硬着头皮来了! 优化
首要我是这么作的,通过httpClient获得HttpEntity,在复制一份Entity,而后通过EntityUtils.toString取得数据内容(信任大多数运用HttpClient的都是这么作),而后从内容里截取出文件头,运用复制的entity取得输入流,越过文件头长度再写文件,大体代码以下: 网站
这里有一个会导致OOM的疑问,便是EntityUtils.toString(responseEntity); 办法,我发如今上载叫大文件的时分会溃散,我想是这个办法会把一切内容读取出来放到内存里,假如文件较大的话天然会溃散,因此这个当地改为了自个写的InputStream2String办法,具体代码不写了,很经常使用,仅有的关键是当读取到一个size的时分(服务器约束的协议头最大长度)就跳出循环不在读取后边的数据,这么内存中最大也便是几k的数据,不会导致OOM了;但是,以前的卡顿状况还是每样处理。 spa
而后开始各类查资料,各类“优化”之后(好比不要在循环里new 目标等),做用仍然不抱负。打开DDMS东西检查Allocation Tracker检查内存分配状况,发现还是下载的那个当地内存较大,原本我也知道HttpEntity responseEntityClone = responseEntity;复制这个当地可能会占用内存,但是也没办法啊,我需求先读取输入流把文件头取出来而后再写文件,但是读取输入流的时分就把responseEntity耗费掉了,后边也写不了文件了。后来俄然想到BufferedReader 有一个readline办法,便是每次读取一行,已\r或者\n作标识,大喜之下尝试了一下,结果很使人失望,下载下来的文件和有损坏。。。失望之下检查了下readline的源码,深受启发!修改了一下InputStream2String的代码,搞定!InputStream2String代码以下: blog
先是一个个字符去读取,当读取到\n的时分,就再也不读了,这么回来的数据恰好是文件头,后边自个也不需求自个去截取data.substring(0,data.indexOf("\n")+1);文件头了,相同,这个inputsream没有耗费完,下面可以接着写文件了,也没必要in.skip(customHeader.length());了 具体网站:http://www.keymob.com/ ip