Open udyr-woo opened 5 days ago
Thanks for reporting. Though I'm not sure there is something ObjectBox can do about this. The root cause is the size of the database and result set being too large for the available memory:
distinctUntilChanged()
on a Flow, DistinctFlowImpl holds onto the previous results to compare them against the new results. So if there are many objects in a result, this requires more memory.What you can try is to
Note: I labeled this issue with "more info required" so it will auto-close in a few days if there are no follow-up comments.
Thanks for reporting. Though I'm not sure there is something ObjectBox can do about this. The root cause is the size of the database and result set being too large for the available memory:
- When using in-memory mode the database is, as the name implies, stored in memory. So when storing many objects it needs more memory than in the regular file-based mode.
- When using
distinctUntilChanged()
on a Flow, DistinctFlowImpl holds onto the previous results to compare them against the new results. So if there are many objects in a result, this requires more memory.What you can try is to
- Reduce the number of objects in the databases to make it consume less memory. Or not use in-memory mode.
- Add more query conditions to reduce the result set size.
- Create a flow on the Box itself and then on changes run a Query with a limit.
Note: I labeled this issue with "more info required" so it will auto-close in a few days if there are no follow-up comments.
Ok. I will do not use in-memory mode. But, If I cancel the flow subscription, shouldn't I close the query and reduce the memory? But I saw that the memory in the native memory area did not decrease and remained the same.
shouldn't I close the query and reduce the memory? But I saw that the memory in the native memory area did not decrease and remained the same.
Yes, the subscription should be canceled and the query closed once done with it. However, native memory is likely managed by the operating system, so it won't be reclaimed when running garbage collection on the Java virtual machine. The operating system should reclaim it once needed.
Note: I labeled this issue with "more info required" so it will auto-close in a few days if there are no follow-up comments.
Build info
Steps to reproduce
OOM generated by calling flow logic while using in-memory mode(but OOM(from java heap) occurs relatively slowly even in file-based mode) And I think it's from a snapshot
Expected behavior
Doesn't increase memory while subscribe flow
Actual behavior
Increase memory a lot
Code
Code
```kotlin DAO @OptIn(ExperimentalCoroutinesApi::class) override fun getInstancesByRepeaterStationIdAndCcuId( repeaterStationId: Short, ccuId: Short ): Flow> { val query = repeaterBox.query(RepeaterEntity_.partialCompositeKey.equal("$repeaterStationId-$ccuId")) .build() return query.subscribe().toFlow().distinctUntilChanged().onCompletion { query.close() } } Entity data class RepeaterEntity( @Id var objectBoxId: Long = 0, @Unique var fullCompositeKey: String = "", @Index var partialCompositeKey: String = "", var repeaterStationId: Short = 0, var ccuId: Short = 0, var id: Short = 0, @Index @Convert(converter = DeviceConnectStatusConverter::class, dbType = String::class) var connect: DeviceConnectStatus = DeviceConnectStatus.CONNECT, @Convert(converter = DeviceConnectStatusConverter::class, dbType = String::class) var previousConnect: DeviceConnectStatus = DeviceConnectStatus.CONNECT, var version: Int = 0, var parentVersion: Long = 0 ) data class RepeaterInputEntity( @Id var objectBoxId: Long = 0, @Unique var fullCompositeKey: String = "", var repeaterStationId: Short = 0, var ccuId: Short = 0, var parentRepeaterId: Short = 0, var id: Short = 0, @Convert(converter = ClassificationConverter::class, dbType = String::class) var classification: Classification = Classification.M1, var signal: Boolean = false, var previousSignal: Boolean = false, var wireBreak: Boolean = false, var outputList: MutableList = mutableListOf(),
var testMode: Boolean = false,
)
data class RepeaterOutputEntity(
@Id
var objectBoxId: Long = 0,
@Unique
var fullCompositeKey: String = "",
var repeaterStationId: Short = 0,
var ccuId: Short = 0,
var parentRepeaterId: Short = 0,
var id: Short = 0,
var signal: Boolean = false,
var request: Boolean = false,
var previousRequest: Boolean = false,
var testMode: Boolean = false,
)
The total number of instances of the three entities combined is 432,000
```
Logs, stack traces