Skip to content

Instantly share code, notes, and snippets.

@dstuebe
Last active April 22, 2018 15:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dstuebe/7b975701f7a1c6a750ed32756c1da858 to your computer and use it in GitHub Desktop.
Save dstuebe/7b975701f7a1c6a750ed32756c1da858 to your computer and use it in GitHub Desktop.
Concurrent MappedByteBuffer error repro case
import java.io.*;
import java.nio.*;
import java.nio.channels.FileChannel;
import java.nio.file.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.IntStream;
import static java.lang.System.exit;
public class HelloProblematicFrame {
public static int pages = 256;
private final int pageSize = 1024 * 256;
private final FileChannel fileChannel;
public static void main(String[] args) {
System.out.println("Starting with: " + String.join(", ", args));
if (args.length != 1) {
System.out.println("must provide a path argument");
exit(1);
}
try {
// new HelloProblematicFrame(Paths.get(args[0])).singleWriteToMappedPages(pages);
new HelloProblematicFrame(Paths.get(args[0])).multipleWriteToMappedPages(pages);
} catch (IOException e) {
System.out.println("Failed to open file at path: " + args[0]);
e.printStackTrace();
exit(1);
}
System.out.println("All Done!");
}
HelloProblematicFrame(Path path) throws IOException {
fileChannel = FileChannel.open(path, StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.READ);
}
void singleWriteToMappedPages(int pages) throws IOException {
// Extending the file ahead of time seems to solve the problem
// fileChannel.map(FileChannel.MapMode.READ_WRITE, pageSize * pages, pageSize).force();
IntStream
.range(0, pages)
.map(val -> val * pageSize)
.boxed()
.sorted(Comparator.comparing(Object::hashCode)) // randomize the order
.parallel()
.map(position -> {
try {
return fileChannel.map(FileChannel.MapMode.READ_WRITE, position, pageSize);
} catch (IOException e) {
throw new UncheckedIOException("Failed to map page at position: " + position, e);
}
})
.map(MappedByteBuffer::duplicate)
.forEach(mappedByteBuffer -> {
mappedByteBuffer.position(pageSize / 2);
mappedByteBuffer.putLong(48853297837222L);
});
}
void multipleWriteToMappedPages(int pages) throws IOException {
// Extending the file ahead of time seems to solve the problem
// fileChannel.map(FileChannel.MapMode.READ_WRITE, pageSize * pages, pageSize).force();
final ConcurrentMap<Long, MappedByteBuffer> bufferMap = new ConcurrentHashMap<>(pages);
ThreadLocalRandom.current()
.longs(pages * 32, 0, pages * (long) pageSize / 8)
.map(val -> val * 8)
.parallel()
.forEach(position -> {
long pageIndexLong = position / pageSize;
long pagePosition = pageIndexLong * pageSize;
int positionInPage = (int) (position % (long) pageSize);
MappedByteBuffer buffer = bufferMap.computeIfAbsent(pageIndexLong, key -> {
try {
return fileChannel.map(FileChannel.MapMode.READ_WRITE, pagePosition, pageSize);
} catch (IOException e) {
throw new UncheckedIOException("Failed to map page at position: " + position, e);
}
});
ByteBuffer duplicate = buffer.duplicate();
duplicate.position(positionInPage);
duplicate.putLong(958936726728432L);
}
);
}
}
$ rm test/problemframe.tst; javac HelloProblematicFrame.java; java -XX:+ShowMessageBoxOnError -XX:ErrorFile=./hs_err_pid%p.log HelloProblematicFrame test/problemframe.tst
rm: test/problemframe.tst: No such file or directory
Starting with: test/problemframe.tst
Exception in thread "main" java.lang.InternalError: java.lang.InternalError: a fault occurred in a recent unsafe memory access operation in compiled Java code
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at java.util.concurrent.ForkJoinTask.getThrowableException(ForkJoinTask.java:593)
at java.util.concurrent.ForkJoinTask.reportException(ForkJoinTask.java:677)
at java.util.concurrent.ForkJoinTask.invoke(ForkJoinTask.java:735)
at java.util.stream.ForEachOps$ForEachOp.evaluateParallel(ForEachOps.java:160)
at java.util.stream.ForEachOps$ForEachOp$OfLong.evaluateParallel(ForEachOps.java:210)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:233)
at java.util.stream.LongPipeline.forEach(LongPipeline.java:385)
at HelloProblematicFrame.multipleWriteToMappedPages(HelloProblematicFrame.java:81)
at HelloProblematicFrame.main(HelloProblematicFrame.java:30)
Caused by: java.lang.InternalError: a fault occurred in a recent unsafe memory access operation in compiled Java code
at sun.nio.ch.FileChannelImpl$Unmapper.<init>(FileChannelImpl.java:816)
at sun.nio.ch.FileChannelImpl$Unmapper.<init>(FileChannelImpl.java:791)
at sun.nio.ch.FileChannelImpl.map(FileChannelImpl.java:957)
at HelloProblematicFrame.lambda$null$4(HelloProblematicFrame.java:87)
at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1660)
at HelloProblematicFrame.lambda$multipleWriteToMappedPages$5(HelloProblematicFrame.java:85)
at java.util.stream.ForEachOps$ForEachOp$OfLong.accept(ForEachOps.java:226)
at java.util.stream.LongPipeline$2$1.accept(LongPipeline.java:214)
at java.util.concurrent.ThreadLocalRandom$RandomLongsSpliterator.forEachRemaining(ThreadLocalRandom.java:893)
at java.util.Spliterator$OfLong.forEachRemaining(Spliterator.java:757)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.ForEachOps$ForEachTask.compute(ForEachOps.java:291)
at java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:731)
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment