android内存分析 outOfMemoryError错误定位及分析策略(非显示图片造成)

三星SMT310平板运行移动学习4.0系统,运行一会儿啥也不干就会报错,闪退。查了一下日志,非图片造成的OOM错误:

06-01 14:16:20.130: D/DBManagerHelper(12700): java.lang.OutOfMemoryError
06-01 14:16:20.130: D/DBManagerHelper(12700): at org.apache.http.util.CharArrayBuffer.expand(CharArrayBuffer.java:59)
06-01 14:16:20.130: D/DBManagerHelper(12700): at org.apache.http.util.CharArrayBuffer.append(CharArrayBuffer.java:77)
06-01 14:16:20.130: D/DBManagerHelper(12700): at org.apache.http.util.EntityUtils.toString(EntityUtils.java:136)
06-01 14:16:20.130: D/DBManagerHelper(12700): at org.apache.http.util.EntityUtils.toString(EntityUtils.java:146)
06-01 14:16:20.130: D/DBManagerHelper(12700): at com.handsome.C_WebServicesTools.HttpRequestHelper.postRequest(HttpRequestHelper.java:84)
06-01 14:16:20.130: D/DBManagerHelper(12700): at com.handsome.A_Activity.SettingsActivity$4.run(SettingsActivity.java:190)
06-01 14:16:20.130: D/DBManagerHelper(12700): at java.lang.Thread.run(Thread.java:856)

1、我擦了,别的平板都不这样,就这个平板有问题,是为什么捏,找到具体错误行数,是:

json.getString("responseList");

2、这也没什么错啊,是因为返回的responseList里面的数据太多造成内存增大么。不对,之前更新数据的时候解析过4 5M的数据都没问题。

3、那是为什么呢,没办法了,看DDMS分析吧,DDMS点击顺序:

4、在右侧heap栏中点击“cause GC" (调用一次GC)即可出现数据

5、发现内存再重新登录后不断的增大,一直到60M,之后就崩了,哭晕在厕所。下个MAT查看详细leak原因:

6、导出hprof文件后,导入MAT报错:

7、百度一下,是由于什么jb玩意,用sdk转换一下就行了:

8、转换完毕后导入MAT,出现以下画面:

9、先点击suspect1的details,查看详细原因,如下图所示:

10、不出所料,还是json解析的问题,单击查看详细引用:

11、查看retained heap,发现占了快5M的内存,把值复制出来一看,竟然有现在和之前请求的所有json数据,崩溃呀,默默的点回我的请求webservice的工具类:

12、两个请求,让我用了static,将请求回来的数据和接下来的解析方法都给同化成static静态方法,造成了请求的所有数据都存入到了内存的静态数据区中,没有被释放。

13、悲剧呀。

14、将static去掉,用单例模式调用,调用方法改为:

String strResult = HttpRequestHelper.getInstance().getRequest(url);

15、再次在SMT310平板运行改程序,不报错了,没问题了。

16、妈蛋,查看了一下智能教学管理系统和智能教学管理系统教师端,都是像上面的调用方法,就移动学习偷懒了,整成static的了,坑了自己一次。

 

未完后续:

17、之后还是崩溃,只不过崩溃的频率比原来少了很多,还是有问题,放到三星not3手机上运行也报错,疯了,看来确实有问题,查看三星手机的报错信息,这回有惊喜了:

java.lang.OutOfMemoryError: Failed to allocate a 8388620 byte allocation with 3853903 free bytes and 3MB until OOM
 at org.apache.http.util.CharArrayBuffer.expand(CharArrayBuffer.java:59)
 at org.apache.http.util.CharArrayBuffer.append(CharArrayBuffer.java:77)
 at org.apache.http.util.EntityUtils.toString(EntityUtils.java:136)
 at org.apache.http.util.EntityUtils.toString(EntityUtils.java:146)
 at com.handsome.C_WebServicesTools.HttpRequestHelper.postRequest(HttpRequestHelper.java:84)
 at com.handsome.C_WebServicesTools.LogicHttpRequest$3.run(LogicHttpRequest.java:102)
 at java.lang.Thread.run(Thread.java:818)

18、百度查:Failed to allocate a 8388620 byte allocation with 3853903 free bytes and 3MB until OOM。

19、很多内容,但是并没有什么帮助,就是一些内存没办法释放的解释。

20、找到HttpRequestHelper 84行,发现EntityUtils.toString(httpResponse.getEntity())报错

21、于是干脆搜:EntityUtils.toString(httpResponse.getEntity()) outofmemory

22、终于找到了问题的答案:

http://blog.csdn.net/wangpeng047/article/details/19624529文章中说:

23、http://www.cppblog.com/iuranus/archive/2010/07/04/119311.html文中这样解释:

24、修改接收方式即可,修改后的接收代码:

          HttpEntity entity = httpResponse.getEntity();
              String result = null;
              if (entity != null)  {     
                  InputStream is = entity.getContent();    
                  result = convertStreamToString(is);     
                  result = result.replace("\n", "");    
                  httpPost.abort();
                 }
              //------------解决OOM方案
              Log.i(TAG, TAG + ":httpPost result :" + result);
              return result;

25、这回终于不报错了

26、其实在第1步的时候就应该按照第20步的方式做,下次就有经验了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值