草庐IT

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

coder 2023-06-07 原文

当我尝试在 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/

有关4G/LTE 上的 Android HttpClient OOM (HTC Thunderbolt)的更多相关文章

  1. ruby-on-rails - date_field_tag,如何设置默认日期? [ rails 上的 ruby ] - 2

    我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问

  2. ruby-on-rails - openshift 上的 rails 控制台 - 2

    我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新ruby​​gems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems

  3. ruby-on-rails - 相关表上的范围为 "WHERE ... LIKE" - 2

    我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que

  4. ruby-on-rails - Ruby - 如何从 ruby​​ 上的 .pfx 文件中提取公钥、rsa 私钥和 CA key - 2

    我有一个.pfx格式的证书,我需要使用ruby​​提取公共(public)、私有(private)和CA证书。使用shell我可以这样做:#ExtractPublicKey(askforpassword)opensslpkcs12-infile.pfx-outfile_public.pem-clcerts-nokeys#ExtractCertificateAuthorityKey(askforpassword)opensslpkcs12-infile.pfx-outfile_ca.pem-cacerts-nokeys#ExtractPrivateKey(askforpassword)o

  5. 带有 attr_accessor 的类上的 Ruby instance_eval - 2

    我了解instance_eval和class_eval之间的基本区别。我在玩弄时发现的是一些涉及attr_accessor的奇怪东西。这是一个例子:A=Class.newA.class_eval{attr_accessor:x}a=A.newa.x="x"a.x=>"x"#...expectedA.instance_eval{attr_accessor:y}A.y="y"=>NoMethodError:undefinedmethod`y='forA:Classa.y="y"=>"y"#WHATTT?这是怎么回事:instance_eval没有访问我们的A类(对象)然后它实际上将它添加到

  6. ruby-on-rails - rails 上的 ruby : radio buttons for collection select - 2

    我有一个集合选择:此方法的单选按钮是什么?谢谢 最佳答案 Rails3中没有这样的助手。在Rails4中,它是collection_radio_buttons. 关于ruby-on-rails-rails上的ruby:radiobuttonsforcollectionselect,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/18525986/

  7. ruby - 将命令行上的变量传递给 Cucumber 测试 - 2

    我正在尝试将cucumber项目的用户名和密码置于版本控制之外。有没有办法在命令行上手动将用户名和密码等变量传递给Cucumber脚本?我的备份计划是将它们放在一个YML文件中,然后将该文件添加到gitignore,这样它们就不会被置于版本控制中。 最佳答案 所以,我看到了您对铁皮人的评论,答案是肯定的。cucumberPASSWORD=my_passwordPASSWORD被设置为环境变量,您可以通过将其引用为ENV['PASSWORD']来使用它的值。例如,browser.text_field(:id=>'pwd').setEN

  8. ruby - 将哈希值保存到 Ruby 上的文件 - 2

    我刚刚迈出了编程的第一步。我刚刚完成了CodeAcademy的另一门类(class)。这次我被要求创建一个小电影目录。这是我的问题:如何在文件中保存/加载带有电影标题和评级的哈希值而不是自己的代码?下面是代码现在的样子(几句葡萄牙语,但您可以忽略它:movies={Memento:3,Primer:4,Ishtar:1}puts"Oquevocêgostariadefazer?"puts"--Digite'add'paraadicionarumfilme."puts"--Digite'update'paraatualizarumfilme."puts"--Digite'display'

  9. ruby - 在 RUBY 上的 PADRINO 框架上使用 RSPEC 进行测试的教程 - 2

    我是Ruby新手,并被要求在我们的新项目中使用它。我们还被要求使用Padrino(Sinatra)作为后端/框架。我们被要求使用Rspec进行测试。我一直在寻找可以指导在Padrino上使用RspecforRuby的教程。我得到的主要是引用RoR。但是,我需要RubyonPadrino。请在任何入门/指南/引用/讨论等方面指导我。如有不妥之处请指正。可能是我没有针对我的问题搜索正确的词/短语组合。我正在使用Ruby1.9.3和Padrinov.0.10.6。注意:我还提到了SOquestion,但它没有帮助。 最佳答案 我没用过Pa

  10. ruby-on-rails - heroku Cedar 上的 CSV - 2

    我想在herokucedar上使用带有rails3.2.1的CSV模块,但是require'CSV'没用这是使用控制台测试时的错误:Loadingproductionenvironment(Rails3.2.1)irb(main):001:0>require'CSV'LoadError:nosuchfiletoload--CSVfrom/app/vendor/bundle/ruby/1.9.1/gems/activesupport-3.2.1/lib/active_support/dependencies.rb:251:in`require'from/app/vendor/bundle

随机推荐