nik*_*kki 13 android out-of-memory
我没有内存错误.我正在进行实时聊天应用程序.它运行正常,但是当我在设备上运行应用程序1到2个小时时,堆大小正在增加,当它达到16 MB时,应用程序开始挂起并在一段时间后崩溃并显示,out of memory due to heap size因为生成的堆大小大于分配.
我在HTC Explorer上测试我的应用程序.在我的应用程序中,大多数活动都使用后台线程,因为我正在使用Asnyc Task.
我收到如下错误.
04-30 16:53:14.658: E/AndroidRuntime(5707): FATAL EXCEPTION: MagentoBackground
04-30 16:53:14.658: E/AndroidRuntime(5707): java.lang.OutOfMemoryError: (Heap Size=20167KB, Allocated=16063KB, Bitmap Size=355KB)
04-30 16:53:14.658: E/AndroidRuntime(5707): at org.apache.http.util.ByteArrayBuffer.<init>(ByteArrayBuffer.java:53)
04-30 16:53:14.658: E/AndroidRuntime(5707): at org.apache.http.impl.io.AbstractSessionInputBuffer.init(AbstractSessionInputBuffer.java:82)
04-30 16:53:14.658: E/AndroidRuntime(5707): at org.apache.http.impl.io.SocketInputBuffer.<init>(SocketInputBuffer.java:98)
04-30 16:53:14.658: E/AndroidRuntime(5707): at org.apache.http.impl.SocketHttpClientConnection.createSessionInputBuffer(SocketHttpClientConnection.java:83)
04-30 16:53:14.658: E/AndroidRuntime(5707): at org.apache.http.impl.conn.DefaultClientConnection.createSessionInputBuffer(DefaultClientConnection.java:170)
04-30 16:53:14.658: E/AndroidRuntime(5707): at org.apache.http.impl.SocketHttpClientConnection.bind(SocketHttpClientConnection.java:106)
04-30 16:53:14.658: E/AndroidRuntime(5707): at org.apache.http.impl.conn.DefaultClientConnection.openCompleted(DefaultClientConnection.java:129)
04-30 16:53:14.658: E/AndroidRuntime(5707): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:173)
04-30 16:53:14.658: E/AndroidRuntime(5707): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
04-30 16:53:14.658: E/AndroidRuntime(5707): at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
04-30 16:53:14.658: E/AndroidRuntime(5707): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:359)
04-30 16:53:14.658: E/AndroidRuntime(5707): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
04-30 16:53:14.658: E/AndroidRuntime(5707): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
04-30 16:53:14.658: E/AndroidRuntime(5707): at com.live2support.CustomHttpClient.executeHttpPost1(CustomHttpClient.java:163)
Run Code Online (Sandbox Code Playgroud)
堆大小有限制吗?我该如何解决我的问题?
Car*_*arl 12
你的问题有两个部分:
1)如何确定测试设备上的堆大小?
2)为什么我的应用程序超出了我的堆大小?
关于问题1,您可以通过调用以下命令直接在代码中确定测试设备上堆的大小:
调用Runtime.getRuntime()maxMemory();
有关该方法的其他信息,以及各种设备上可用的一些示例堆大小,请参阅此文章.
此外,如果您正在运行root设备,可能有一种方法可以通过接口直接设置(并检查)堆大小.例如,在CyanogenMod的各种版本的Android中,从"设置"菜单中,您可以选择"CyanogenMod设置",然后选择"性能",然后选择"VM堆大小",并直接查看(和更改)设备的堆大小.请注意,因为将堆大小设置得太小会使您的设备出现异常或更糟.
关于问题2:您没有提供足够的信息来诊断您的具体问题,而且无论如何,二手做这样的诊断充其量是困难的.解决这个问题(以及在过程中学习持久价值的东西)的最佳选择是熟悉Android中可用的一些非常强大的内存分析工具(其中一些也集成到Eclipse IDE中).我使用Eclipse中的这些工具,这就是我将在下面描述的内容.
首先,通过安装最新版本的Eclipse(例如,Indigo)来确保您的Eclipse版本是最新的.
接下来,在Eclipse中,选择"帮助/安装新软件",然后单击顶部的下拉列表并选择
"Indigo - http://download.eclipse.org/releases/indigo"
Run Code Online (Sandbox Code Playgroud)
接下来,通过单击旁边的加号打开通用工具类别,然后选择Memory Analyzer和Memory Analyzer(图表)[可选].安装这些工具.
接下来,选择Window/Preferences,然后选择Android/DDMS,并选择HPROF操作为"在Eclipse中打开".这将导致您从DDMS生成的任何HPROF堆转储文件具有适当的Eclipse格式,并且还会导致它在Eclipse的Memory Analyzer(刚刚安装在上面)中自动打开.
现在,通过选择Window/Open Perspective/Other/DDMS打开DDMS.选择左侧的"设备"图标(看起来像手机),然后拖动生成的窗口,使其停靠在您可以轻松看到的位置.
确保您的设备通过USB连接到PC,并确保您的应用正在运行.
在刚刚创建的"设备"选项卡中,选择正在运行的应用程序进程.运行应用程序到它已经占用足够的内存,你知道它已泄露,但不是太多,它崩溃.现在,单击设备选项卡中的转储HPROF文件图标.在短暂的延迟之后,您将获得堆上的报告选择.尝试泄漏嫌疑人报告即可开始使用.此报告将在内存分析工具中打开.它会告诉您应用在哪里使用内存.检查各种对象,看它们是否相对于您期望它们所需的数据量而变得臃肿; 如果是这样,那可能表明存在泄漏.
这是一个很好的教程,更详细地描述了如何使用DDMS和Memory Analyzer Tool生成和探索堆.
回到DDMS(或Eclipse中的DDMS透视图),您可以在连接设备时选择Allocation Tracker选项卡,然后从设备选项卡中选择设备,然后从该设备的列表中选择应用程序的进程.然后,在"分配跟踪器"选项卡中,单击"开始跟踪"按钮,然后运行应用程序的相关操作(您怀疑正在泄漏的操作),然后单击"获取分配"按钮,然后选择"停止跟踪"按钮.
这将显示您在跟踪时发生的所有分配(它将存储的数量有限制).单击其中任何一个将在分配时将您带到堆栈,单击该堆栈转储的任何部分将转到分配中涉及的源代码.
这些工具可以让您深入了解可能导致应用程序泄漏内存的原因.
它看起来像是经典的内存泄漏.你说,你AsyncTask用来连接.当您不知道如何正确使用它时,很容易在配置更改(例如设备旋转)上使用AsyncTask泄漏上下文.
第一件事 - 我强烈建议你看这个:http://www.youtube.com/watch?v = _CruQY55HOk
要检查是否存在此类内存泄漏,请旋转设备并检查垃圾收集器的行为方式.GC_... freed 211K, 71% free 300K/1024K, external 0K/0K, paused 1ms+1ms几乎每次旋转时都应该在LogCat中有类似的东西.注意这部分的变化:300K/1024K.如果没有内存泄漏,第一部分应该增长,然后在几个GC之后变小.如果你有内存泄漏,它会增长和增长,达到OOM错误的程度.
如果你确保你有这样的内存泄漏,你应该做的是安装MAT for Eclipse,学习如何使用它(与前面提到的电影)并找出它的原因.
我个人的赌注是AsyncTask的糟糕实现 - 你是否将它从被销毁的Activity中分离并将其附加到新的?如果没有,开始这样做(这是CommonsWare的一个很好的例子)或切换到AsyncTaskLoader它为你做的,并且通常是一个很好的替代品AsyncTask(不仅用于加载东西).
小智 5
只需 android:largeHeap="true"在清单中添加应用程序标签即可。
| 归档时间: |
|
| 查看次数: |
17614 次 |
| 最近记录: |