首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >4G/LTE上的Android HttpClient OOM (宏达雷电)

4G/LTE上的Android HttpClient OOM (宏达雷电)
EN

Stack Overflow用户
提问于 2011-03-18 21:28:33
回答 3查看 5.8K关注 0票数 21

当我尝试在Verizon的4G/LTE上使用我的应用程序时,我从用户那里得到了一些关于崩溃的报告。

查看堆栈跟踪,它看起来像是Android的HttpClient.execute()实现正在抛出一个OOM。这种情况只发生在4G/LTE设备上,特别是HTC,只有在4G/LTE上才会出现。WiFi,3G,UMTS都很好。在Sprint的WiMax 4G上也很好用。

两个问题:

  • ,什么是吸引安卓开发人员注意的最好方法?还有比报告http://code.google.com/p/android/issues
  • Any的想法更好的选择吗?我可以如何解决这个问题?我自己没有4G设备,我无法在模拟器中实现这一点,所以我需要在这里做一些有根据的猜测。我可以尝试在代码中捕获OOM,并尝试清理和强制GC,但我不确定这是否是一个好主意。评论或其他建议?

下面是我的代码所做的:

代码语言:javascript
运行
复制
    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堆(11639):2055696字节分配的内存不足.I/dalvikvm(11639):"Thread-16“prio=5 tid=9 RUNNABLE I/dalvikvm(11639):group="main”main“sCount=0 dsCount=0 s=N obj=0x48563070 self=0x3c4340 I/dalvikvm(11639):self=0x3c4340=0/0 cgrp=default handle=3948760 I/dalvikvm(11639):x-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:(11639):在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(org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465) I/dalvikvm(11639):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):内存不足:堆Size=24171KB,Allocated=23142KB,Bitmap Size=59KB,Limit=21884KB E/dalvikvm(11639):额外信息: Footprint=24327KB,with Footprint=24519KB,Trimmed=348KB W/dalvikvm(11639):threadid=9:线程退出与未指明的异常(group=0x40025b38)

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-03-18 22:09:56

查看堆栈跟踪,它看起来像是Android的HttpClient.execute()实现正在抛出一个OOM。

这不是由您对问题的堆栈跟踪所指示的。当然,您没有提供关于这个问题的整个堆栈跟踪。

有比在http://code.google.com/p/android/issues上报道更好的选择吗?

这是一个纯粹的Android错误的可能性很小,虽然不是零。

以下是其他一些可能性,不按特定顺序排列:

  1. 本身没有问题,但你只是内存不足,而你所遇到的堆栈跟踪只是证明了execute()在压力你的堆。
  2. 问题在于HTC对Android所做的一些修改,只有在LTE网络上才能生效。
  3. 这个问题在某种程度上是由威瑞森LTE网络本身引起的(例如,他们的代理发送了一些螺丝球信息,导致HttpClient拥有了一个HttpClient。)

关于我如何解决这个问题,

有什么想法吗?

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

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

作为一种权宜之计,你可以通过android.os.Build数据检测到你在雷电上运行,也许你是通过ConnectivityManager在LTE上运行(我猜LTE会被列为WiMAX,但这只是猜测),并警告用户使用这种组合的问题。

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

如果您只支持API级别8或更高版本,则可以将replacement

  • Disable多线程访问(一般情况下或特定于雷霆的访问)给AndroidHttpClient一次尝试,并摆脱ThreadSafeClientConnManager

很抱歉我这里没有“魔法子弹”的答案。

更新

现在我已经有了完整的堆栈跟踪,在一定程度上查看了源代码is...illuminating。

问题似乎是:

代码语言:javascript
运行
复制
HttpConnectionParams.getSocketBufferSize(params);

返回触发OOM的2MB左右的值。这是一个非常大的缓冲区,特别是对于Dalvik GC引擎来说,它可以变得支离破碎(是的,还有这个词)。

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

代码语言:javascript
运行
复制
HttpConnectionParams.setSocketBufferSize(params, 8192);

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

票数 26
EN

Stack Overflow用户

发布于 2011-05-14 01:18:30

以下是修复方法:https://review.source.android.com/22852

同时,URLConnection是免疫的。只有HttpClient才有这个问题。

如果您是一个想要测试这种失败的开发人员,您可以使用“亚行外壳设置支持”来设置"net.tcp.buffersize.wifi“,这样当设备使用wifi时,最大的读/写套接字缓冲区大小就会很大。下面这样的东西将是一个真正的压力测试:

代码语言:javascript
运行
复制
adb shell setprop net.tcp.buffersize.wifi 4096,80999999,80999999,4096,80999999,80999999

正是这种配置更改使用了HttpClient错误。我不知道Thunderbolt上的确切值是多少,但是有这个设备的人可以使用“亚行外壳getprop \ grep缓冲区大小”来找出答案。

票数 4
EN

Stack Overflow用户

发布于 2011-06-08 10:35:29

也许这会有帮助:

代码语言:javascript
运行
复制
// Set the timeout in milliseconds until a connection is established.
int timeoutConnection = 5000;

// Set the default socket timeout (SO_TIMEOUT) 
// in milliseconds which is the timeout for waiting for data.
int timeoutSocket = 4000;

// set timeout parameters for HttpClient 
HttpParams httpParameters = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
HttpConnectionParams.setSocketBufferSize(httpParameters, 8192);//setting setSocketBufferSize

DefaultHttpClient httpClient = new DefaultHttpClient();
httpClient.setParams(httpParameters);
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5358014

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档