gpt4 book ai didi

4G/LTE 上的 Android HttpClient OOM (HTC Thunderbolt)

转载 作者:IT老高 更新时间:2023-10-28 23:05:16 27 4
gpt4 key购买 nike

当我尝试在 Verizon 的 4G/LTE 上使用我的应用程序时,我收到了一些来自用户的崩溃报告。

查看堆栈跟踪,看起来 Android 的 HttpClient.execute() 实现正在引发 OOM。这仅在 4G/LTE 设备(特别是 HTC Thunderbolt)上发生,并且仅在 4G/LTE 上发生。 WiFi、3G、UMTS 都可以。在 Sprint 的 WiMax 4G 上也可以正常工作。

两个问题:

  • 什么是引起 Android 开发者注意的最佳方式?比报告 http://code.google.com/p/android/issues 更好的选择?

  • 关于如何解决这个问题有什么想法吗?我自己没有 4G 设备,我无法在模拟器中发生这种情况,所以我需要在这里做出一些有根据的猜测。我可以尝试在我的代码中捕获 OOM 并尝试清理和强制 GC,但我不确定这是否是个好主意。意见或其他建议?

这是我的代码的作用:

    HttpParams params = this.getHttpParams(); // returns params
ClientConnectionManager cm = new ThreadSafeClientConnManager(params, this.getHttpSchemeRegistry() );
DefaultHttpClient httpClient = new DefaultHttpClient( cm, params );

HttpResponse response = null;
request = new HttpGet( url );

try {

response = httpClient.execute(request); // <-- OOM on 4G/LTE. OK otherwise
int statusCode = response.getStatusLine().getStatusCode();
Log.i("fetcher", "execute returned, http status " + statusCode );

...

这是崩溃的堆栈跟踪:

E/dalvikvm-heap(11639): Out of memory on a 2055696-byte allocation. I/dalvikvm(11639): "Thread-16" prio=5 tid=9 RUNNABLE I/dalvikvm(11639): | group="main" sCount=0 dsCount=0 s=N obj=0x48563070 self=0x3c4340 I/dalvikvm(11639): | sysTid=11682 nice=0 sched=0/0 cgrp=default handle=3948760 I/dalvikvm(11639): | schedstat=( 208709711 74005130 214 )

I/dalvikvm(11639): at org.apache.http.impl.io.AbstractSessionInputBuffer.init(AbstractSessionInputBuffer.java:~79) I/dalvikvm(11639): at org.apache.http.impl.io.SocketInputBuffer.(SocketInputBuffer.java:93) I/dalvikvm(11639): at org.apache.http.impl.SocketHttpClientConnection.createSessionInputBuffer(SocketHttpClientConnection.java:83) I/dalvikvm(11639): at org.apache.http.impl.conn.DefaultClientConnection.createSessionInputBuffer(DefaultClientConnection.java:170) I/dalvikvm(11639): at org.apache.http.impl.SocketHttpClientConnection.bind(SocketHttpClientConnection.java:106) I/dalvikvm(11639): at org.apache.http.impl.conn.DefaultClientConnection.openCompleted(DefaultClientConnection.java:129) I/dalvikvm(11639): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:173) I/dalvikvm(11639): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164) I/dalvikvm(11639): at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119) I/dalvikvm(11639): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:348) I/dalvikvm(11639): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555) I/dalvikvm(11639): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487) I/dalvikvm(11639): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465) I/dalvikvm(11639): at com.myapplication.Fetcher.trySourceFetch(Fetcher.java:205) I/dalvikvm(11639): at com.myapplication.Fetcher.run(Fetcher.java:298) I/dalvikvm(11639): at java.lang.Thread.run(Thread.java:1102) I/dalvikvm(11639): E/dalvikvm(11639): Out of memory: Heap Size=24171KB, Allocated=23142KB, Bitmap Size=59KB, Limit=21884KB E/dalvikvm(11639): Extra info: Footprint=24327KB, Allowed Footprint=24519KB, Trimmed=348KB W/dalvikvm(11639): threadid=9: thread exiting with uncaught exception (group=0x40025b38)

最佳答案

Looking at the stack trace, it looks like Android's HttpClient.execute() implementation is throwing an OOM.

您在该问题上的堆栈跟踪并未表明这一点。当然,您没有提供有关该问题的完整堆栈跟踪。

What's the best way to get the attention of Android devs about this? Any better options than reporting on http://code.google.com/p/android/issues?

这是一个纯 Android 错误的可能性很小,尽管不是零。

以下是其他一些可能性,排名不分先后:

  1. execute() 本身没有问题,但你只是内存不足,你遇到的堆栈跟踪只是证明 execute( ) 给你的堆带来压力。

  2. 问题在于 HTC 对 Android 的 Thunderbolt 进行了一些修改,可能仅在 LTE 网络上生效。

  3. 这个问题是由 Verizon LTE 网络本身引起的(例如,他们的一些代理发回导致 HttpClient 有一个 conniption 的怪诞信息)。

Any ideas on how I can work around this?

首先,我会使用现有工具(例如,转储 HPROF 并使用 Eclipse MAT 检查)来确认您一般没有内存泄漏,Thunderbolt/LTE 组合似乎只是被绊倒了。

接下来,我建议您想出一些方法来持续重现错误。这可能是您现有的应用程序,需要遵循一系列步骤,或者它可能是一个专用应用程序(例如,记录触发 OOM 的 URL,然后创建一个只执行该 HttpClient 请求的小型应用程序)。我希望 DeviceAnywhere 有一个 Thunderbolt,但它看起来不像。我会试探一下,看看能不能在这方面得到一些帮助。

就解决它而言,作为权宜之计,您可以通过 android.os.Build 数据检测到您正在 Thunderbolt 上运行,也许您正在通过 ConnectivityManager(我猜 LTE 会列为 WiMAX,但这只是一个猜测),并警告用户该组合存在的问题。

除此之外,您可以尝试稍微更改一下您的 HttpClient 使用情况,看看它是否有效果,例如:

  • 如果您只支持 API Level 8 或更高版本,您可以尝试使用 AndroidHttpClient 作为替代品
  • 禁用多线程访问(一般或特定于 Thunderbolt)并摆脱 ThreadSafeClientConnManager

很抱歉,我在这里没有“ Elixir ”的答案。


更新

现在我有了完整的堆栈跟踪,查看源代码……有点启发性。

问题似乎是:

HttpConnectionParams.getSocketBufferSize(params);

正在返回触发 OOM 的 2MB 左右的值。这是一个非常大的缓冲区,特别是对于 Dalvik GC 引擎,它可能会变得 fragment 化(是的,又是那个词)。

params 这里是 HttpParams。您似乎是通过 getHttpParams() 自己创建的。例如,AndroidHttpClient 将其设置为 8192:

HttpConnectionParams.setSocketBufferSize(params, 8192);

如果您自己设置套接字缓冲区大小,请尝试减小它。如果没有,请尝试将其设置为 8192,看看是否有帮助。

关于4G/LTE 上的 Android HttpClient OOM (HTC Thunderbolt),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5358014/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com