When you call Dataset#close()
, the implementation delegates that call to an underlying
DatasetGraphBase#close()
, which then ultimately delegates to DatasetGraphTDB#_close()
.
This results in calls to TripleTable#close()
and QuadTable#close()
. Both of these call (several) NodeTupleTable#close()
. Continuing with the indirection, this calls NodeTable#close()
and TupleTable#close()
. The former is an interface, so we'd need to make a proper guess as to which class is run in your implementation. The latter iterates through a collection of TupleIndex
objects and calls close()
on each of them. TupleIndex
is, also, an interface.
There is only one meaningful heirarchy of descendents from TupleIndex
that results in something which can lock a file, which leads us to TupleIndexRecord#close()
. We can then follow a particular implementation of RangeIndex
called BPlusTree
all the way down until we see actual ownership of the MappedByteBuffer
Ultimately, while reading the implementation of BlockAccessMapped#close()
, it seems like the entire heirarchy is closing things properly, down to the final classes, but that this longstanding bug may be the culprit. From the documentation:
once a file has been mapped a number of operations on that file will fail until the mapping has been released (e.g. delete, truncating to a size less than the mapped area). However the programmer can't control accurately the time at which the unmapping takes place --- typically it depends on the processing of finalization or a PhantomReference queue.
So there you have it. Despite Jena's best efforts, one cannot yet control when that file will be unmapped in Java. This ends up being the tradeoff for memory-mapped file IO in java.