Мне нужно вставить около 150 миллионов записей в базу данных Xodus, используя пакет xodus-dnq. Основываясь на примерах, я реализовал следующий метод:
XdModel.registerNodes(
XDTrip
)
val store = StaticStoreContainer.init(
dbFolder = File(target),
environmentName = "trips"
)
initMetaData(XdModel.hierarchy, store)
store.use { store ->
store.persistentStore.use {
// TripLoader(File(src)) returns a stream with roughly 150M elements
TripLoader(File(src)).forEach { databaseTrip ->
store.transactional {
XDTrip.new {
id = databaseTrip.id
start = databaseTrip.start.epochSecond
end = databaseTrip.end.epochSecond
}
}
}
}
}
Это прекрасно работает, но утечки памяти. Предположительно мне нужно вручную зафиксировать / очистить / сохранить транзакцию?
На основании другого предложения я реорганизовал это для запуска меньших пакетов внутри транзакции:
XdModel.registerNodes(
XDTrip,
XDPosition,
XDPositionSource
)
val store = StaticStoreContainer.init(
dbFolder = File(target),
environmentName = "trips"
)
initMetaData(XdModel.hierarchy, store)
store.use {
it.use { store ->
Sequence { TripLoader(File(src)).iterator() }.chunked(100).forEachIndexed { index, csvChunk ->
store.transactional {
println("Chunk $index")
csvChunk.forEach { csvTrip ->
XDTrip.new {
id = csvTrip.id
start = csvTrip.start.epochSecond
end = csvTrip.end.epochSecond
// ...
}
}
}
}
}
}
Это, тем не менее, приводит к утечке памяти.
Я проанализировал память и нашел экземпляр jetbrains.exodus.core.dataStructures.ConcurrentLongObjectCache
, занимающий большую часть кучи:
Один экземпляр "jetbrains.exodus.core.dataStructures.ConcurrentLongObjectCache", загруженный "sun.mis c .Launcher $ AppClassLoader @ 0x4c0481d58" занимает 45 075 952 (80,24%) байта. Память накапливается в одном экземпляре "jetbrains.exodus.core.dataStructures.ConcurrentLongObjectCache $ CacheEntry []", загруженном "sun.mis c .Launcher $ AppClassLoader @ 0x4c0481d58".
Keywords Jetbrains.ex .core.dataStructures.ConcurrentLongObjectCache sun.mis c .Launcher $ AppClassLoader @ 0x4c0481d58 jetbrains.exodus.core.dataStructures.ConcurrentLongObjectCache $ CacheEntry []
* * * * * * * * * * * * * * * * * *
1019 * 1019 пока программа работает, поэтому я не уверен, почему кэш заполняется здесь.