I find that when the database is not fitted in memory and there are a lot of parallel scan going on. It needs to get some IN record directly from the file. This causes too many random seek IO. Even though the entire set of data resides in file system cache, there are many calls like the stack trace below. I wonder what I can do to make the scan to be much faster and reduce the GC problem. The record size is around 200 bytes and each LogManager.getLogEntry seems to allocate around 2K of memory. This seems to have a significant impact to GC heavily given that we are trying to scan several hundred thousand records per second from multiple threads.
java.lang.Thread.State: RUNNABLE
at java.io.RandomAccessFile.seek0(Native Method)
at java.io.RandomAccessFile.seek(RandomAccessFile.java:557)
at com.sleepycat.je.log.FileManager.readFromFileInternal(FileManager.java:1907)
- locked <0x00000001f7011dd8> (a com.sleepycat.je.log.FileManager$DefaultRandomAccessFile)
at com.sleepycat.je.log.FileManager.readFromFile(FileManager.java:1862)
at com.sleepycat.je.log.FileManager.readFromFile(FileManager.java:1799)
at com.sleepycat.je.log.FileSource.getBytes(FileSource.java:92)
at com.sleepycat.je.log.LogManager.getLogEntryFromLogSource(LogManager.java:909)
at com.sleepycat.je.log.LogManager.getLogEntry(LogManager.java:826)
at com.sleepycat.je.log.LogManager.getLogEntryAllowInvisibleAtRecovery(LogManager.java:788)
at com.sleepycat.je.tree.IN.fetchLN(IN.java:2808)
at com.sleepycat.je.tree.IN.fetchLN(IN.java:2746)
at com.sleepycat.je.dbi.CursorImpl.getCurrent(CursorImpl.java:2235)
at com.sleepycat.je.dbi.CursorImpl.lockAndGetCurrent(CursorImpl.java:2083)
at com.sleepycat.je.dbi.CursorImpl.getNext(CursorImpl.java:2552)
at com.sleepycat.je.Cursor.retrieveNextNoDups(Cursor.java:3064)
at com.sleepycat.je.Cursor.retrieveNext(Cursor.java:2836)
at com.sleepycat.je.Cursor.getNext(Cursor.java:1117)
at com.sleepycat.util.keyrange.RangeCursor.doGetNext(RangeCursor.java:1126)
at com.sleepycat.util.keyrange.RangeCursor.getNext(RangeCursor.java:650)
at com.sleepycat.persist.BasicCursor.next(BasicCursor.java:116)
at com.sleepycat.persist.BasicIterator.hasNext(BasicIterator.java:85)
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x000000017a22c300> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:870)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1199)
at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:209)
at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:285)
at java.util.concurrent.ArrayBlockingQueue.offer(ArrayBlockingQueue.java:327)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1361)
at com.sleepycat.je.evictor.Evictor.alert(Evictor.java:2179)
at com.sleepycat.je.evictor.Evictor.doCriticalEviction(Evictor.java:2041)
at com.sleepycat.je.dbi.EnvironmentImpl.criticalEviction(EnvironmentImpl.java:2880)
at com.sleepycat.je.dbi.CursorImpl.criticalEviction(CursorImpl.java:776)
at com.sleepycat.je.dbi.CursorImpl.close(CursorImpl.java:693)
at com.sleepycat.je.Cursor.endMoveCursor(Cursor.java:4683)
at com.sleepycat.je.Cursor.retrieveNextNoDups(Cursor.java:3072)
at com.sleepycat.je.Cursor.retrieveNext(Cursor.java:2836)
at com.sleepycat.je.Cursor.getNext(Cursor.java:1117)
at com.sleepycat.util.keyrange.RangeCursor.doGetNext(RangeCursor.java:1126)
at com.sleepycat.util.keyrange.RangeCursor.getNext(RangeCursor.java:650)
at com.sleepycat.persist.BasicCursor.next(BasicCursor.java:116)
at com.sleepycat.persist.BasicIterator.hasNext(BasicIterator.java:85)