/users文件夹中的数据库有将近50,000个用户记录,我无法读取密钥,因为它充满了内存。
这发生在移动设备上的java环境中,以及具有firebase功能的服务器上的javaScript中。
数据库启用了持久性。
在两个环境中,datanapshot.getChildrenCount()文件夹中的一个简单的/users ()已经耗尽了内存。
如何全面读取所有用户的所有唯一密钥以将其存储在本地列表中?
下面是我使用的代码示例:
爪哇:
public void getUsersCount() {
ref.child("users").addListenerForSingleValueEvent(new ValueEventListener() {
public void onDataChange(@NonNull DataSnapshot datasnapshot) {
Log.w("tag", "TOTAL: " + datasnapshot.getChildrenCount() + " users");
// for (DataSnapshot snap : datasnapshot.getChildren()) {
// list.add(snap.getKey() + "");
// }
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) { }
});
}
OutOfMemoryError:
2022-03-03 18:02:13.043 1512-1591/com.xxxx.xxxR W/om.xxxx.xxx: Throwing OutOfMemoryError "Failed to allocate a 69318664 byte allocation with 25149440 free bytes and 62MB until OOM, target footprint 496333008, growth limit 536870912" (VmSize 8600872 kB)
2022-03-03 18:02:13.787 1512-1591/com.xxxx.xxxR W/om.xxxx.xxx: Throwing OutOfMemoryError "Failed to allocate a 69318664 byte allocation with 25165824 free bytes and 62MB until OOM, target footprint 496274696, growth limit 536870912" (VmSize 8600872 kB)
2022-03-03 18:02:13.790 1512-1591/com.xxxx.xxxR E/RunLoop: Firebase Database encountered an OutOfMemoryError. You may need to reduce the amount of data you are syncing to the client (e.g. by using queries or syncing a deeper path). See https://firebase.google.com/docs/database/ios/structure-data#best_practices_for_data_structure and https://firebase.google.com/docs/database/android/retrieve-data#filtering_data
java.lang.OutOfMemoryError: Failed to allocate a 69318664 byte allocation with 25165824 free bytes and 62MB until OOM, target footprint 496274696, growth limit 536870912
at java.lang.StringFactory.newStringFromChars(StringFactory.java:112)
at java.lang.StringBuilder.toString(StringBuilder.java:413)
at java.util.AbstractCollection.toString(AbstractCollection.java:464)
at java.lang.String.valueOf(String.java:2924)
at java.lang.StringBuilder.append(StringBuilder.java:132)
at java.util.AbstractMap.toString(AbstractMap.java:559)
at java.lang.String.valueOf(String.java:2924)
at java.lang.StringBuilder.append(StringBuilder.java:132)
at com.google.firebase.database.connection.PersistentConnectionImpl.onDataPush(PersistentConnectionImpl.java:950)
at com.google.firebase.database.connection.PersistentConnectionImpl.onDataMessage(PersistentConnectionImpl.java:522)
at com.google.firebase.database.connection.Connection.onDataMessage(Connection.java:167)
at com.google.firebase.database.connection.Connection.onMessage(Connection.java:131)
at com.google.firebase.database.connection.WebsocketConnection.appendFrame(WebsocketConnection.java:259)
at com.google.firebase.database.connection.WebsocketConnection.handleIncomingFrame(WebsocketConnection.java:302)
at com.google.firebase.database.connection.WebsocketConnection.access$500(WebsocketConnection.java:34)
at com.google.firebase.database.connection.WebsocketConnection$WSClientTubesock$2.run(WebsocketConnection.java:86)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:462)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:920)
2022-03-03 18:02:13.795 1512-1512/com.xxxx.xxxR E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.xxxx.xxxR, PID: 1512
java.lang.RuntimeException: Firebase Database encountered an OutOfMemoryError. You may need to reduce the amount of data you are syncing to the client (e.g. by using queries or syncing a deeper path). See https://firebase.google.com/docs/database/ios/structure-data#best_practices_for_data_structure and https://firebase.google.com/docs/database/android/retrieve-data#filtering_data
at com.google.firebase.database.android.AndroidPlatform$1$1.run(AndroidPlatform.java:96)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.app.ActivityThread.main(ActivityThread.java:8641)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:567)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1133)
Caused by: java.lang.OutOfMemoryError: Failed to allocate a 69318664 byte allocation with 25165824 free bytes and 62MB until OOM, target footprint 496274696, growth limit 536870912
at java.lang.StringFactory.newStringFromChars(StringFactory.java:112)
at java.lang.StringBuilder.toString(StringBuilder.java:413)
at java.util.AbstractCollection.toString(AbstractCollection.java:464)
at java.lang.String.valueOf(String.java:2924)
at java.lang.StringBuilder.append(StringBuilder.java:132)
at java.util.AbstractMap.toString(AbstractMap.java:559)
at java.lang.String.valueOf(String.java:2924)
at java.lang.StringBuilder.append(StringBuilder.java:132)
at com.google.firebase.database.connection.PersistentConnectionImpl.onDataPush(PersistentConnectionImpl.java:950)
at com.google.firebase.database.connection.PersistentConnectionImpl.onDataMessage(PersistentConnectionImpl.java:522)
at com.google.firebase.database.connection.Connection.onDataMessage(Connection.java:167)
at com.google.firebase.database.connection.Connection.onMessage(Connection.java:131)
at com.google.firebase.database.connection.WebsocketConnection.appendFrame(WebsocketConnection.java:259)
at com.google.firebase.database.connection.WebsocketConnection.handleIncomingFrame(WebsocketConnection.java:302)
at com.google.firebase.database.connection.WebsocketConnection.access$500(WebsocketConnection.java:34)
at com.google.firebase.database.connection.WebsocketConnection$WSClientTubesock$2.run(WebsocketConnection.java:86)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:462)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:920)
发布于 2022-03-03 23:24:47
DataSnapshot
对象包含填充它的路径或查询上的所有数据的快照。因此,您所称的“简单datanapshot.getChildrenCount()
”实际上是读取整个users
节点,这显然比设备占用更多的内存。
修复此问题的第一步是停止读取所有节点,以确定节点计数。相反,您应该将节点计数值存储在数据库中,并在添加/删除节点时更新该值。如何这样做的一个很好的例子,可以在Cloud中的子计数示例中找到。
如果您需要处理所有用户节点,您可以使用API的limitToFirst
和startAt
/startAfter
方法,在批/片中这样做。
https://stackoverflow.com/questions/71343943
复制相似问题