android 修复内存不足错误

zc0qhyus  于 2023-01-19  发布在  Android
关注(0)|答案(3)|浏览(332)
    • bounty将于明天过期**。此问题的答案可获得+350的声誉奖励。Etienne Lawlor正在寻找来自声誉良好来源的答案:我需要获得一些解决问题的详细信息

大家好,我看到最近Android版本中内存泄漏导致的崩溃大幅增加。我们已经做了一些事情来缓解这些问题,但在最新版本中仍然看到同样的崩溃。

Fatal Exception: java.lang.OutOfMemoryError
 Failed to allocate a 16 byte allocation with 1890136 free bytes and 1845KB until OOM, target footprint 201326592, growth limit 201326592; failed due to fragmentation (largest possible contiguous allocation 54788096 bytes)
 java.lang.Long.valueOf (Long.java:845)
 io.reactivex.internal.operators.observable.ObservableInterval$IntervalObserver.run (ObservableInterval.java:82)
 io.reactivex.Scheduler$PeriodicDirectTask.run (Scheduler.java:562)
 io.reactivex.Scheduler$Worker$PeriodicTask.run (Scheduler.java:509)
 io.reactivex.internal.schedulers.ExecutorScheduler$ExecutorWorker$BooleanRunnable.run (ExecutorScheduler.java:288)
 io.reactivex.internal.schedulers.ExecutorScheduler$ExecutorWorker.run (ExecutorScheduler.java:253)
 java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1167)
 java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:641)
 java.lang.Thread.run (Thread.java:923)
Fatal Exception: java.lang.OutOfMemoryError
 Failed to allocate a 16 byte allocation with 1590248 free bytes and 1552KB until OOM, target footprint 201326592, growth limit 201326592; failed due to fragmentation (largest possible contiguous allocation 39845888 bytes)
 io.reactivex.internal.schedulers.ExecutorScheduler$ExecutorWorker.schedule (ExecutorScheduler.java:161)
 io.reactivex.internal.schedulers.ExecutorScheduler$ExecutorWorker.schedule (ExecutorScheduler.java:187)
 io.reactivex.Scheduler$Worker$PeriodicTask.run (Scheduler.java:531)
 io.reactivex.internal.schedulers.ExecutorScheduler$ExecutorWorker$BooleanRunnable.run (ExecutorScheduler.java:288)
 io.reactivex.internal.schedulers.ExecutorScheduler$ExecutorWorker.run (ExecutorScheduler.java:253)
 java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1167)
 java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:641)
 java.lang.Thread.run (Thread.java:923)
Fatal Exception: java.lang.OutOfMemoryError
 Failed to allocate a 16 byte allocation with 1215008 free bytes and 1186KB until OOM, target footprint 201326592, growth limit 201326592; failed due to fragmentation (largest possible contiguous allocation 49020928 bytes)
 io.reactivex.internal.queue.MpscLinkedQueue.offer (MpscLinkedQueue.java:62)
 io.reactivex.internal.schedulers.ExecutorScheduler$ExecutorWorker.schedule (ExecutorScheduler.java:167)
 io.reactivex.internal.schedulers.ExecutorScheduler$ExecutorWorker.schedule (ExecutorScheduler.java:187)
 io.reactivex.Scheduler$Worker$PeriodicTask.run (Scheduler.java:531)
 io.reactivex.internal.schedulers.ExecutorScheduler$ExecutorWorker$BooleanRunnable.run (ExecutorScheduler.java:288)
 io.reactivex.internal.schedulers.ExecutorScheduler$ExecutorWorker.run (ExecutorScheduler.java:253)
 java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1167)
 java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:641)
 java.lang.Thread.run (Thread.java:923)

是否有一些框架变化触发了这些问题,是应用程序代码导致了这些问题?有哪些策略可以尝试解决类似上述的崩溃?

2uluyalo

2uluyalo1#

除了现有的评论之外,还需要考虑其他一些技术:

现场 Jmeter :

活动模式:如果您有记录用户活动的工具,请查找长时间未崩溃的应用程序和较早崩溃的应用程序,并查看用户是否执行了不同的操作
直接内存使用:由于您还无法在调试构建版本中重现这一情况,您可以记录特定活动前后的可用内存,以帮助您缩小应用中发生这种情况的位置。您可以访问app available memory,然后记录它(如果您可以获得日志)或通过一些分析系统报告它。

本地测试:

(with Canary或分析器泄漏)
通常会有一些时间点应返回到相同级别的已分配内存:例如,如果你进入一个屏幕,然后再出来,你可能会分配一些静态项目,但从第二次使用屏幕开始,你会希望内存恢复正常(静态)点。因此停止执行,强制执行GC,重新开始执行并通过工作流,然后返回主屏幕。(再次跳过第一次)可以是缩小哪个工作流留下大量额外内存的范围的好方法。
调试版本不产生这种效果是不寻常的,如果您有一个“友好”的最终用户报告了这个问题,也许可以给予他们一个调试版本,并要求他们通过使用它来支持您。
在调试环境中,您还可以尝试“使其变得更糟”,例如,进出屏幕或工作流10或100次(脚本用于100次示例)。

92dk7w1h

92dk7w1h2#

不能动态增加堆大小,但可以使用请求使用更多堆。
android:largeHeap="true"
manifest.xml中,您可以在清单中添加它在某些情况下工作的这些行。

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:largeHeap="true"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">

应用程序的进程是否应该用一个大的Dalvik堆创建。这适用于为应用程序创建的所有进程。它只适用于加载到进程中的第一个应用程序;如果你使用共享用户ID来允许多个应用程序使用一个进程,则它们都必须一致地使用此选项,否则将产生不可预测的结果。大多数应用程序不需要此选项,而应专注于减少其总体内存使用量以提高性能。启用此选项也不能保证可用内存的固定增加,因为某些设备受其总可用内存的限制。
要在运行时查询可用内存大小,请使用方法getMemoryClass()或getLargeMemoryClass()。

oymdgrw7

oymdgrw73#

使用Coroutines进行长时间或繁重的操作。这些崩溃来自Rxjava。可能您在其中没有准确地执行工作。

相关问题