三星Galaxy设备在Android 7.x上出现很多OutOfMemoryError错误。

9
我在Google Play商店有一个活跃的应用程序。几个月以来,我在Play Console上收到了很多奇怪的崩溃报告。
由于我无法在这里粘贴所有数据(有很多崩溃报告),因此我试图展示一个好的摘要。如需详细信息,请联系我。
受影响最多的设备:
- 三星 Galaxy A5 2016(a5xelte) - 三星 Galaxy S5(klte) - 三星 Galaxy A5(2017)(a5y17lte) - 三星 Galaxy Note3(hlte) - 三星 Galaxy S5 Neo(s5neolte) - 三星 Galaxy S6(zeroflte)
注意:与其他设备相比,第一个设备非常关键
崩溃类型:
- 在android.app.ActivityThread.performLaunchActivity中的java.lang.RuntimeException - 在java.lang.StringFactory.newStringFromBytes中的java.lang.OutOfMemoryError - 在libcore.util.CharsetUtils.toUtf8Bytes中的java.lang.OutOfMemoryError - 在java.lang.StringFactory.newStringFromChars中的java.lang.OutOfMemoryError - 在java.lang.StringBuilder.toString中的java.lang.OutOfMemoryError - 在java.lang.StringFactory.newStringFromChars中的java.lang.OutOfMemoryError Android版本:7.0、7.1和偶尔的6.0
我不知道为什么这些设备会出现这种情况,也不知道如何调试这些报告,并且我在StackOverflow或其他来源中没有找到类似的问题。有任何帮助吗?
编辑,一些堆栈跟踪:
三星 Galaxy A5(2016)(a5xelte),2048MB RAM,Android 7.0
java.lang.RuntimeException: 
  at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2984)
  at android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:3045)
  at android.app.ActivityThread.-wrap14 (ActivityThread.java)
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1642)
  at android.os.Handler.dispatchMessage (Handler.java:102)
  at android.os.Looper.loop (Looper.java:154)
  at android.app.ActivityThread.main (ActivityThread.java:6776)
  at java.lang.reflect.Method.invoke (Method.java)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:1496)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1386)

三星 Galaxy S6 Edge(zerolte),3072MB RAM,Android 7.0。
java.lang.OutOfMemoryError: 
  at java.lang.StringFactory.newStringFromBytes (StringFactory.java:185)
  at java.lang.StringFactory.newStringFromBytes (StringFactory.java:63)
  at android.util.Base64.encodeToString (Base64.java:456)
  at org.chromium.android_webview.AwContents.loadDataWithBaseURL (AwContents.java:428)
  at com.android.webview.chromium.WebViewChromium.loadDataWithBaseURL (WebViewChromium.java:188)
  at android.webkit.WebView.loadDataWithBaseURL (WebView.java:1015)
  at com.google.android.gms.ads.internal.webview.p.loadDataWithBaseURL (p.java:131)
  at com.google.android.gms.ads.internal.webview.o.loadDataWithBaseURL (o.java:104)
  at com.google.android.gms.ads.internal.renderer.i.a (i.java:8)
  at com.google.android.gms.ads.internal.renderer.a.c (a.java:35)
  at com.google.android.gms.ads.internal.renderer.g.a (g.java:11)
  at com.google.android.gms.ads.internal.zzk.run (zzk.java:28)
  at android.os.Handler.handleCallback (Handler.java:751)
  at android.os.Handler.dispatchMessage (Handler.java:95)
  at android.os.Looper.loop (Looper.java:154)
  at android.app.ActivityThread.main (ActivityThread.java:6682)
  at java.lang.reflect.Method.invoke (Method.java)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:1520)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1410)

三星Galaxy A5(2016) (a5xelte),内存为2048MB,运行Android 7.0操作系统。
java.lang.OutOfMemoryError: 
  at libcore.util.CharsetUtils.toUtf8Bytes (CharsetUtils.java)
  at java.lang.String.getBytes (String.java:879)
  at java.lang.String.getBytes (String.java:851)
  at org.chromium.android_webview.AwContents.loadDataWithBaseURL (AwContents.java:428)
  at com.android.webview.chromium.WebViewChromium.loadDataWithBaseURL (WebViewChromium.java:188)
  at android.webkit.WebView.loadDataWithBaseURL (WebView.java:1015)
  at com.google.android.gms.ads.internal.webview.p.loadDataWithBaseURL (p.java:131)
  at com.google.android.gms.ads.internal.webview.o.loadDataWithBaseURL (o.java:104)
  at com.google.android.gms.ads.internal.renderer.i.a (i.java:8)
  at com.google.android.gms.ads.internal.renderer.a.c (a.java:35)
  at com.google.android.gms.ads.internal.renderer.g.a (g.java:11)
  at com.google.android.gms.ads.internal.zzk.run (zzk.java:28)
  at android.os.Handler.handleCallback (Handler.java:751)
  at android.os.Handler.dispatchMessage (Handler.java:95)
  at android.os.Looper.loop (Looper.java:154)
  at android.app.ActivityThread.main (ActivityThread.java:6776)
  at java.lang.reflect.Method.invoke (Method.java)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:1496)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1386)

编辑2: 我已更新 firebase-ads 的依赖项,但仍然遇到相同的崩溃。此外,在这个版本中我还遇到了一个新的崩溃类型:

三星 Galaxy A5(2016) (a5xelte),2048MB RAM,Android 7.0

java.lang.InternalError: 
  at java.lang.Thread.nativeCreate (Thread.java)
  at java.lang.Thread.start (Thread.java:731)
  at java.util.concurrent.ThreadPoolExecutor.addWorker (ThreadPoolExecutor.java:941)
  at java.util.concurrent.ThreadPoolExecutor.processWorkerExit (ThreadPoolExecutor.java:1009)
  at java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1151)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:607)
  at java.lang.Thread.run (Thread.java:762)

1
请发布完整的堆栈跟踪,而不仅仅是错误消息。 - CommonsWare
编辑后带有一些堆栈跟踪。 - Antonio Papalillo
1
后两者来自Play服务的广告代码。确保您使用的是其库的最新版本。 - CommonsWare
我在Android 7和7.1上也遇到了RuntimeExceptions。我们的项目中正在使用firebase通知。 - Rafael
这个bug是去年报告的。Admob只是假设这是用户实现的问题,并关闭了这个问题。 :( https://groups.google.com/forum/#!topic/google-admob-ads-sdk/xtnAcmnPYFI - Angel Koh
显示剩余2条评论
2个回答

5

我本不想用这种方式来解决,但是似乎只能通过添加来解决

largeHeap="true"

添加到我的清单中。

我发现的是:三星Galaxy设备的内存被三星公司优化得很差(Galaxy A5 2016年版有2GB RAM,这足够了,但在Firebase上,我可以看到由于堆非常小而导致的OOM)。因此,我决定一劳永逸地解决这些问题,并将largeHeap设置为true。我对这个选择并不感到骄傲,但它似乎是唯一可行的。

结果:所有的OOMs似乎都已经消失了,至少目前是这样。


这有助于解决第一个列出的错误吗?在 android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2984) 中发生了 RuntimeException 错误(三星 Galaxy A5)。 - OferR
@OferR 你应该发布完整的堆栈跟踪。 - Antonio Papalillo
我的问题是这个解决方案是否帮助您解决了您在问题中列出的问题。就是您列出的第一个堆栈跟踪。在应用largeHeap="true"之后,这些错误是否消失了? (我所指的问题是您列出的第一个问题。它显示了android.app.ActivityThread.performLaunchActivity中的RuntimeException,而您的其他堆栈跟踪则显示了OutOfMemoryError)...谢谢... - OferR
@OferR 是的,对我来说确实有帮助。但也可能是其他原因,因为RuntimeException不一定是由于堆太小而抛出的。如果您在三星设备上遇到了很多类似的堆栈跟踪,可以尝试设置largeHeap="true",可能会解决问题。如果您这样做了,请再次回到这里,让其他用户知道它是否有帮助。 - Antonio Papalillo
谢谢。我会的。我不会遇到太多这样的错误,但这些错误总是出现在三星设备(包括S8)上,并且总是在performLaunchActivity上。 - OferR

4

让我们逐段查看最后一个堆栈跟踪:

java.lang.OutOfMemoryError: 
  at libcore.util.CharsetUtils.toUtf8Bytes (CharsetUtils.java)
  at java.lang.String.getBytes (String.java:879)
  at java.lang.String.getBytes (String.java:851)

所以,引起问题的具体原因是将一个String转换成了一个byte[]。要么你的堆空间非常短缺,要么那个字符串非常大。

  at org.chromium.android_webview.AwContents.loadDataWithBaseURL (AwContents.java:428)
  at com.android.webview.chromium.WebViewChromium.loadDataWithBaseURL (WebViewChromium.java:188)
  at android.webkit.WebView.loadDataWithBaseURL (WebView.java:1015)

因此,我们可以看到使用loadDataWithBaseURL()的是WebViewString。 这表明某些内容正在使用一个较大的URL调用loadDataWithBaseURL()data: URL是其中一种可能性。

  at com.google.android.gms.ads.internal.webview.p.loadDataWithBaseURL (p.java:131)
  at com.google.android.gms.ads.internal.webview.o.loadDataWithBaseURL (o.java:104)
  at com.google.android.gms.ads.internal.renderer.i.a (i.java:8)
  at com.google.android.gms.ads.internal.renderer.a.c (a.java:35)
  at com.google.android.gms.ads.internal.renderer.g.a (g.java:11)
  at com.google.android.gms.ads.internal.zzk.run (zzk.java:28)

在这里,我们有六行代码都来自同一个Java包。 com.google.android.gms 是许多Play服务的顶级包,因此com.google.android.gms.ads 可能是其广告库之一。我不常使用Play服务,所以对于他们仍然拥有哪些广告网络品牌以及哪些品牌与com.google.android.gms.ads 相对应并不是很了解。

因此,请检查您的广告网络库,并确保您正在使用最新和最好的版本。运气好的话,这可能是他们在某个时候修复的错误。


谢谢你指出来。我在firebase-corefirebase-ads上都使用了旧版本。我希望最新的发布可以解决所有与Galaxy设备有关的问题(包括performLaunchActivity上的匿名RuntimeException)。十分期待:) - Antonio Papalillo
1
@AndroidGuy:对于第一个堆栈跟踪,如果没有更多信息,你就无能为力了。没有任何标识特征指向你的代码或库。而且,如果这是你得到的全部内容,考虑使用其他方法获取崩溃日志。通常这些堆栈跟踪有多个段落(RuntimeException和一堆行,然后是Caused by和另一个异常和一堆行)。你真正的问题可能在后面的段落中报告,但如果你没有那部分堆栈跟踪,你就没办法了。 - CommonsWare
这就是问题所在。但我注意到,第一份堆栈跟踪中的所有崩溃都来自Android 7.0上的Galaxy设备。这让我想到它与firebase-ads库或firebase-core中的问题有关(它们都有相同的旧版本号)。我发布了一个更新,使这两个库保持最新状态。如果这不起作用,我已经将firebase-crash添加到依赖项中,它将启用到Firebase控制台的崩溃报告,希望它能帮助我获得更准确的堆栈跟踪。 - Antonio Papalillo
不幸的是,最近的更新似乎没有修复任何问题。请查看主贴中的第二次编辑。 - Antonio Papalillo
@AndroidGuy:如果没有更多的崩溃日志细节,很难甚至不可能准确找到这种崩溃的源头。 - CommonsWare

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接