java特种兵读书笔记(4-2)——java通信之IO与内存
2016-01-18 15:45
337 查看
常规IO操作过程
java程序普通的IO过程,都会经历从Kernel到JVM的内存拷贝。
例如做一次文件拷贝,一般会开启一个输入流,将文件读取到JVM内存中,然后开启一个输出流,将内存中数据输出到另一个文件中(一个文件->kernel->JVM内存->另一个文件)。
不是磁盘->磁盘,不是磁盘->内存,而是会经历一个内核区。
拷贝内存速度很快,但是反复大量拷贝也有很大开销。可以跳过JVM拷进拷出。
高层次抽象与低层次抽象的效率问题
低层次抽象的拷贝未必就比高层次抽象的拷贝快多少,因为在IO直接交互的位置产生瓶颈(最终磁盘到OS的页面交换速度本身的瓶颈,所以有可能数据堵在kernel,而没有写入到终端)。
内存映射
这块区域直接映射到磁盘上,用FileChannel.map()在磁盘对应位置直接分配一块空间,类似虚拟内存,负责返回一个MappedByteBuffer类型的对象(本质也是DirectByteBuffer,只是它直接映射到磁盘上),这并不代表它没有缓冲区,只是通过OS来控制。此时对该ByteBuffer直接写入数据,就直接写入磁盘了,省去了拷贝的过程。
JDK1.7之后,使用Files.copy()方法简单很多。
Buffer
Cache是将数据就近存储,存取方便。
Buffer通常与IO相关,是IO交互过程的一个缓冲区,达到一次交互一批信息而不是一个字节信息的目的。
BufferXXXStream和BufferReader/Writer就是Buffer使用代表,使用java的一个数组来完成,将对应的流修饰后,使得输入输出过程自动产生Buffer功能。
HeapByteBuffer在java heap中分配空间,DirectByteBuffer在C heap中分配空间。
flip()方法将limit设置为当前position位置,将position设置为0,将mark设置为-1。该动作为了获取Buffer中[0,position]当中的所有数据(即Buffer中现有的所有数据)。flip将limit放在数据有效位置的末尾,以便于读取所有有效数据。
clear()将limit放在总容量最后的位置,以便于重新写入数据。但是此时数据还在,可以从这里面读取数据。
remaining()是limit-position的值,即剩余空间。
FileChannel加锁
FileChannel可以通过FileXXXStream,RandomAccessFile的getChannel()方法来获得。
它有加锁功能,lock()方法如果拿不到锁会阻塞,tryLock()方法拿不到锁会返回null,拿到了会返回FileLock对象。
需要关闭锁的时候,使用release()即可。
java程序普通的IO过程,都会经历从Kernel到JVM的内存拷贝。
例如做一次文件拷贝,一般会开启一个输入流,将文件读取到JVM内存中,然后开启一个输出流,将内存中数据输出到另一个文件中(一个文件->kernel->JVM内存->另一个文件)。
不是磁盘->磁盘,不是磁盘->内存,而是会经历一个内核区。
拷贝内存速度很快,但是反复大量拷贝也有很大开销。可以跳过JVM拷进拷出。
高层次抽象与低层次抽象的效率问题
低层次抽象的拷贝未必就比高层次抽象的拷贝快多少,因为在IO直接交互的位置产生瓶颈(最终磁盘到OS的页面交换速度本身的瓶颈,所以有可能数据堵在kernel,而没有写入到终端)。
内存映射
这块区域直接映射到磁盘上,用FileChannel.map()在磁盘对应位置直接分配一块空间,类似虚拟内存,负责返回一个MappedByteBuffer类型的对象(本质也是DirectByteBuffer,只是它直接映射到磁盘上),这并不代表它没有缓冲区,只是通过OS来控制。此时对该ByteBuffer直接写入数据,就直接写入磁盘了,省去了拷贝的过程。
JDK1.7之后,使用Files.copy()方法简单很多。
Buffer
Cache是将数据就近存储,存取方便。
Buffer通常与IO相关,是IO交互过程的一个缓冲区,达到一次交互一批信息而不是一个字节信息的目的。
BufferXXXStream和BufferReader/Writer就是Buffer使用代表,使用java的一个数组来完成,将对应的流修饰后,使得输入输出过程自动产生Buffer功能。
HeapByteBuffer在java heap中分配空间,DirectByteBuffer在C heap中分配空间。
flip()方法将limit设置为当前position位置,将position设置为0,将mark设置为-1。该动作为了获取Buffer中[0,position]当中的所有数据(即Buffer中现有的所有数据)。flip将limit放在数据有效位置的末尾,以便于读取所有有效数据。
clear()将limit放在总容量最后的位置,以便于重新写入数据。但是此时数据还在,可以从这里面读取数据。
remaining()是limit-position的值,即剩余空间。
FileChannel加锁
FileChannel可以通过FileXXXStream,RandomAccessFile的getChannel()方法来获得。
它有加锁功能,lock()方法如果拿不到锁会阻塞,tryLock()方法拿不到锁会返回null,拿到了会返回FileLock对象。
需要关闭锁的时候,使用release()即可。
相关文章推荐
- Java Web学习总结(17)——JSP属性范围
- Java Web学习总结(16)——JSP的九个内置对象
- Java Web学习总结(16)——JSP的九个内置对象
- Java7的异常处理新特性-addSuppressed()方法等
- Eclipse智能提示及快捷键
- Java Web学习总结(15)——JSP指令
- JAVA加密解密之DH(Diffie-Hellman)算法
- Java-如何去掉JFrame上的最大化最小化和关闭按钮(转)
- javaThread学习(chapter1—线程的创建)
- Java学习之Iterator(迭代器)的一般用法 (转)
- JAVA的extends用法
- java通用日期转换(string 转 date)
- Spring配置文件中的 default-lazy-init="true"
- java入门学习(10)—抽象类
- Java细节之static方法重写
- 【菜鸟学Java】10:Cookie技术
- JAVA加密解密之PBE(Password Based Encryption)算法
- 使用myeclipse打jar包
- Java Web学习总结(14)——JSP基础语法
- Java Web学习总结(14)——JSP基础语法