Skip to content

java nio

Posted on:February 3, 2024 at 10:04 PM

背景

了解java的nio,因为在看到lucene的MappedByteBuffer , 所以想了解一下nio的内容 nio 主要包括三个内容:

linux 的epoll

在linux里面 , 这是封装了epoll , java 的selector的open对应的就是epoll_create1

apireturn
epoll_create1(flag)On success, these system calls return a nonnegative file descriptor. On error, -1 is returned, and errno is set to indicate the error.
epoll_ctlWhen successful, epoll_ctl() returns zero. When an error occurs, epoll_ctl() returns -1 and errno is set appropriately.
#include <stdio.h>     // for fprintf()
#include <unistd.h>    // for close()
#include <sys/epoll.h> // for epoll_create1()

int main()
{
	int epoll_fd = epoll_create1(0);
	
	if (epoll_fd == -1) {
		fprintf(stderr, "Failed to create epoll file descriptor\n");
		return 1;
	}

	if (close(epoll_fd)) {
		fprintf(stderr, "Failed to close epoll file descriptor\n");
		return 1;
	}

	return 0;
}

Buffer

ByteBuffer

例子

简单的例子:

    @Test
    public void fileChannel()
            throws IOException {
        try (FileChannel fc = FileChannel.open(Paths.get("ccc.cc"),StandardOpenOption.WRITE , StandardOpenOption.READ ,StandardOpenOption.CREATE) ) {
            MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_WRITE, 0, 1);
            byte b = 97;
            bb.put(0 ,b  );
            fc.write(bb);
            var charset = Charset.defaultCharset();
            System.out.println( "res" + charset.decode(bb).toString());
        }
    }

其实调用:

    @ForceInline
    public void put$Type$(Scope scope, Object base, long offset, $type$ value) {
        try {
            put$Type$Internal(scope, base, offset, value);
        } catch (Scope.ScopedAccessError ex) {
            throw new IllegalStateException("This segment is already closed");
        }
    }

    @ForceInline @Scoped
    private void put$Type$Internal(Scope scope, Object base, long offset, $type$ value) {
        try {
            if (scope != null) {
                scope.checkValidState();
            }
            UNSAFE.put$Type$(base, offset, value);
        } finally {
            Reference.reachabilityFence(scope);
        }
    }

最后写在这里

  void put(T x) {
    GuardUnsafeAccess guard(_thread);
    *addr() = normalize_for_write(x);
  }

整个流程就是: mmap返回的是一个指针 ,MappedByteBuffer 调用UNSAFE.put方法直接修改堆外内存的值,不经过堆

java force 强制刷新

FileDispatcherImplforce0

JNIEXPORT jint JNICALL
Java_sun_nio_ch_FileDispatcherImpl_force0(JNIEnv *env, jobject this,
                                          jobject fdo, jboolean md)
{
    jint fd = fdval(env, fdo);
    int result = 0;

    result = fcntl(fd, F_FULLFSYNC);
    if (result == -1) {
        struct statfs fbuf;
        int errno_fcntl = errno;
        if (fstatfs(fd, &fbuf) == 0) {
            if ((fbuf.f_flags & MNT_LOCAL) == 0) {
                /* Try fsync() in case file is not local. */
                result = fsync(fd);
            }
        } else {
            /* fstatfs() failed so restore errno from fcntl(). */
            errno = errno_fcntl;
        }
    }

    return handle(env, result, "Force failed");
}

相关阅读