У нас была похожая проблема около 2015 года, после того, как пользователь на Win7 / x64 регулярно находил оставшиеся файлы, которые не были удалены после завершения программы. После некоторых исследований и проб и ошибок мы обнаружили, что это произошло только с файлами, которые недавно были сопоставлены с памятью, и исправили это, избегая сопоставления памяти с файлами, которые мы хотели удалить скоро / позже.
FileChannelImpl.transferFromFileChannel
Память отображает источник для передачи. (Зависит от вашей JVM - я основываю это на OpenJDK.) Несмотря на то, что JVM очищает после копирования путем отмены сопоставления, тем самым делая недействительным созданное представление, ОС может отложить фактическую очистку до другого момента времени. Пока этого не происходит, файл имеет действующую (но недоступную) карту памяти, которая может препятствовать удалению ссылок.
Похоже, этот вопрос связан с: Как правильно закрыть MappedByteBuffer?
Для ссылка: jdk11 / sun.nio.ch.FileChannelImpl # TransferFromFileChannel
private long transferFromFileChannel(FileChannelImpl src,
long position, long count)
throws IOException
{
if (!src.readable)
throw new NonReadableChannelException();
synchronized (src.positionLock) {
long pos = src.position();
long max = Math.min(count, src.size() - pos);
long remaining = max;
long p = pos;
while (remaining > 0L) {
long size = Math.min(remaining, MAPPED_TRANSFER_SIZE);
// ## Bug: Closing this channel will not terminate the write
MappedByteBuffer bb = src.map(MapMode.READ_ONLY, p, size);
try {
long n = write(bb, position);
assert n > 0;
p += n;
position += n;
remaining -= n;
} catch (IOException ioe) {
// Only throw exception if no bytes have been written
if (remaining == max)
throw ioe;
break;
} finally {
unmap(bb);
}
}
long nwritten = max - remaining;
src.position(pos + nwritten);
return nwritten;
}
}