// 查看文件的缓存状态
~ pcstat out.txt
//查看文件张多大了
~ ll -h
//查看文件长多大了同时查看文件的缓存状态
~ ll -h & pcstat out.txt
pcstat 结果说明,size 文件大小,pages总页数,cached已缓存的页数
image.png
程序访问内存的时候,只要内存空间足够,cache会一直不断的缓存
page cache优化IO性能,但是会导致数据丢失
//最基本的file写,直接进行系统调用,进行写操作
@Test
public static void testBasicFileIo() throws Exception{
File file = new File(path);
FileOutputStream out = new FileOutPutStream(file);
while(true){
out.write(data);
}
}
/**buffer文件IO,jvm会自己留出8k的缓存,buffer write的时候,会先往缓存中写,8kb满了之后,
再进行系统调用写操作,把jvm缓存区的内容写入到系统中
jvm 8kb syscall write(8KBbyte[])
*/
@Test
public static void testBufferedFileIO() throws Exception{
File file = new File(path);
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file));
while(true){
out.write(data);
}
}
FileChannel rafChannel = raf.getChannel();
// mmap 堆外和文件映射的
MappedByteBuffer map = rafChannel.map(FileChannel.MapMode.READ_WRITE,0,4096);
map.put("@@@".getBytes()); // 不是系统调用 但是数据会到达内核的pagecache
// 曾经我们是需要out.write() 这样的系统调用,才能让程序的data进入内核的pagecache
// 曾经必须有用户态内核太切换
// 虽然此处不在需要用户态与内核太进行切换,通过这种mmap的内存映射,依然是受内核的pagecache体系所约束的!!!换言之,这种方式也会出现断电丢数据的情况
@Test
public void whatByteBuffer(){
// 还有一个要注意的地方,ByteBuffer是jdk中提供的,ByteBuf是Netty中提供的,ByteBuf是对ByteBuffer的封装
// ByteBuffer buffer = ByteBuffer.allocate(1024);
ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
System.out.println("position:" + buffer.position());
System.out.println("limit:" + buffer.limit());
System.out.println("capacity:" + buffer.capacity());
buffer.put("123".getBytes());
System.out.println("------------------------put:123-----");
System.out.println("mark:" + buffer);
buffer.filp();
System.out.println("mark:" + buffer);
buffer.get();
System.out.println("mark:" + buffer);
buffer.compact();
System.out.println("mark:" + buffer);
buffer.clear();
System.out.println("mark:" + buffer);
}
jvm文件处理在linux中的内存模型
IO模型2.png
模型图片的脚上的内容是磁盘,内部包含一个文件
模型图片的头上是个Object对象,一个圆圈
网友评论