ROOM OutOfMemoryError R(OOM)

8

我在我的play-console中看到了这些错误。有人知道如何最好地处理room中的OOM错误吗?

java.lang.OutOfMemoryError: 
  at android.database.CursorWindow.nativeGetString (Native Method)
  at android.database.CursorWindow.getString (CursorWindow.java:451)
  at android.database.AbstractWindowedCursor.getString (AbstractWindowedCursor.java:51)
  at org.walleth.data.transactions.TransactionDAO_Impl$8.compute (TransactionDAO_Impl.java:1272)
  at org.walleth.data.transactions.TransactionDAO_Impl$8.compute (TransactionDAO_Impl.java:1212)
  at android.arch.lifecycle.ComputableLiveData$2.run (ComputableLiveData.java:87)
  at java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1133)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:607)
  at java.lang.Thread.run (Thread.java:762)

除非那是一个非常巨大的“字符串”,否则Room可能不是你的问题,而只是你崩溃的地方。OOM有两个触发器:请求太大的内存块(考虑“位图”)或由于某个地方的泄漏而真正耗尽内存。在后一种情况下,你崩溃的地方恰好是你最终耗尽内存的地方,但不一定是泄漏的地方。你是否收到了这种崩溃日志的变体,告诉你分配失败的大小有多大? - CommonsWare
很不幸,我没有崩溃日志的变体,可以看到分配失败的大小。但它可能是一个巨大的字符串(数据字段在某些情况下可能很大)- 有没有办法捕获这个OOM并忽略这个项目(最有可能是合同部署,而我对此也不感兴趣)? - ligi
你没有很好地捕获那个特定的异常,因为它发生在一个你无法控制的后台线程上,并且LiveData不会传播异常。考虑不让你的DAO返回LiveData,而是使用RxJava类型。或者,在DAO中将此查询同步,并安排在自己的后台线程上调用@Query方法。 - CommonsWare
这个问题能通过将查询作为事务来解决吗?https://developer.android.com/reference/android/arch/persistence/room/Transaction.html 很难从日志中知道确切的原因,但也许你可以尝试一下,看看是否有所帮助。 - emirua
1
重新考虑一下,这可能无法解决内存不足错误,因为它将执行相同的操作,只是在查询过大时更加一致。如果您正在更新任何内容,它只能帮助您确保数据准确性以防查询期间出现错误。这些是最麻烦的错误,因为似乎您甚至无法定位哪个查询有问题。 - emirua
显示剩余2条评论
1个回答

2

您是否一次传输大量数据?

如果您正在填写列表,则可以懒惰地进行操作,并且例如每次获取100个。

此外,如果您从数据库中获取的响应具有许多列,请仅SELECT使用的列。


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