您的位置:首页 > 移动开发 > Android开发

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

2016-06-01 16:01 429 查看
三星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步的方式做,下次就有经验了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android OOM