JVM被MappedByteBuffer杀死

时间:2014-03-03 23:19:57

标签: java jvm

我有这个功能:

    private double[] readTableDouble(final RandomAccessFile file, final long startIndex, final int length) throws IOException {
    double[] doubles;
    try (FileChannel channel = file.getChannel()) {
        MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, startIndex * 8, length * 8);
        int byteIndex = buffer.limit() - 8;
        doubles = new double[length];
        int doubleIndex = 0;
        while (byteIndex > 0 && doubleIndex < length) {
            long l = 0;
            for (int i = 0; i < 8; i++) {
                l |= ((long) (buffer.get(byteIndex + i) & 0xFF)) << i * 8;
            }
            byteIndex -= 8;
            if (l != fillerLong) {
                doubles[doubleIndex++] = Double.longBitsToDouble(l);
            }
        }
        if (doubleIndex == length) {
            file.close();
            channel.close();
            return doubles;
        }

        // try again from the start if not enough numbers
        buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, (startIndex + length) * 8);
        byteIndex = buffer.limit() - 8;
        doubleIndex = 0;
        while (byteIndex > 0 && doubleIndex < length) {
            long l = 0;
            for (int i = 0; i < 8; i++) {
                l |= ((long) (buffer.get(byteIndex + i) & 0xFF)) << i * 8;
            }
            byteIndex -= 8;
            if (l != fillerLong) {
                doubles[doubleIndex++] = Double.longBitsToDouble(l);
            }
        }
    }
    file.close();
    return doubles;
}

由于某种原因,它会导致JVM死机,并出现以下错误:

Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x000000077f280000, 13107200, 0) failed; error='Cannot allocate memory' (errno=12)
There is insufficient memory for the Java Runtime Environment to continue.
Native memory allocation (malloc) failed to allocate 13107200 bytes for committing reserved memory.
An error report file with more information is saved as:
/home/lukasz/Documents/NetBeansProjects/PPP/hs_err_pid8817.log
Java Result: 1

此函数被调用数十万次,但返回的缓冲区很快被释放。没有多线程,文件大约是340kB。

任何想法为什么? Profiler与JVM一起被杀死。

1 个答案:

答案 0 :(得分:0)

没有明确定义MappedByteBuffer分配的VM可以释放的时间,因此永远不会释放。因此,在Java中打开大量内存映射文件存在很大问题。