- 浏览: 213923 次
- 性别:
- 来自: 广州
文章分类
- 全部博客 (107)
- java网络通信(rmi,hessian,nio...) (4)
- java基础 (25)
- java压缩和解压缩 (1)
- 开发框架整合 (7)
- struts2.0 (3)
- 构建工具(ant,maven..) (1)
- web容器配置(tomcat,weblogic,nginx...) (3)
- hibernate (8)
- 业务(项目管理,项目设计相关) (5)
- 数据库(oracle,mysql..) (7)
- linux命令 (6)
- java网络通信(rmi (6)
- hessian (6)
- nio...) (6)
- 数据库(oracle (4)
- mysql..) (4)
- ibatis (2)
- 多线程 (1)
- Windows Install Clean Up 卸载JDK (1)
- IETEST (1)
- UML 类图 关系 (1)
- java基础 spring (2)
- NFS SFU (1)
- jmap mat jps (1)
- 架构 (1)
- 统一管理 (0)
- 项目管理 (1)
- 图片预加载 (1)
- 代码高亮 (1)
- 同步 (1)
- 权限管理 (0)
- ehcache ibatis (1)
- jd-gui proguard (1)
- portmon (1)
- procexp (1)
- mysql (1)
- NIO 内存映射文件 (1)
- web容器配置(tomcat (1)
- weblogic (1)
- nginx...) (1)
- WEB (1)
- html (1)
- javascript (1)
- iOS pods (1)
最新评论
-
vrbvillor:
我的QQ是245614005。如果您可以帮我的话,请发邮件或联 ...
mysql存储过程中使用动态SQL,并且返回值 -
vrbvillor:
大侠,请教一个问题。我想在mysql的function里边 ...
mysql存储过程中使用动态SQL,并且返回值 -
newslxw:
ppgunjack 写道关键要弄清楚,UAT用例是谁提供,谁评 ...
做到客户满意为止(项目成本控制相关主题) -
萧十一狼:
所有dao类都继承com.ibatis.sqlmap.clie ...
spring+ibatis整合方法 -
adss101:
一般项目就这块比较难控制,,弄不好就死在这了,,客户要求,对于 ...
做到客户满意为止(项目成本控制相关主题)
java的内存映射文件有如下特点:
1,使用虚拟内存,因此分配(map)的内存大小不受JVM的-Xmx参数限制,但是也是有大小限制的,首先他理论上不能超过Integer.MAX_VALUE也就是32位操作系统的2G,其次,其实际值在不用操作系统还不一样,在win7 32位操作系统下,他不能超过1.5G,具体多少,没测出来,也不知道什么原因。
2, 对应读大文件,当文件超出1.5G限制是,可以重新MAP下,通过POSITION参数来获取文件后面的内容。
3,它的读取和来回读取要不普通IO快的多,但是单纯的写入还不如普通I/O的一般速度。此结论来自以下测试代码
package com.chat; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.ByteBuffer; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import java.nio.channels.FileChannel.MapMode; public class FileChannelStudy { static String filename1 = "d:\\work\\code\\filechannelstudy.txt"; static String filename2 = "d:\\work\\code\\file.txt"; static String content = "abcdefghijk\r\n"; static long size = 1024000000l; static long num = size / 10*6; static long startT = 0; static long endT = 0; public static void setStartT() { mbb = null; if(cnt %50 == 0) { System.gc(); System.out.println("call gc"); } startT = System.currentTimeMillis(); } public static long ellipseT() { endT = System.currentTimeMillis(); long consumeT = endT - startT; System.out.println("consume time :"+ consumeT/1000 + " second"); return consumeT / 1000; } /** * @param args * @throws IOException */ public static void main(String[] args) throws IOException { // readFile1(); createFile(true); preparedFile1(); preparedFile2(); } public static void createFile(boolean bReCreate) throws IOException { if(!bReCreate) { File f = new File(filename1); if(!f.exists()) f.createNewFile(); f = new File(filename2); if(!f.exists()) f.createNewFile(); } else { File f = new File(filename1); if(f.exists()) f.delete(); f.createNewFile(); f = new File(filename2); if(f.exists()) f.delete(); f.createNewFile(); } } public static void preparedFile2() throws IOException { BufferedOutputStream bo = new BufferedOutputStream(new FileOutputStream(filename2)); try { System.out.println("fill file by io"); setStartT(); for (int i = 0; i < num; i++) { bo.write(content.getBytes()); } ellipseT(); } finally { if(bo != null) bo.close(); } } public static void preparedFile1() throws IOException { long mapsize = content.getBytes().length*1000000*100; long position = 0; FileChannel ch = new RandomAccessFile(filename1,"rw").getChannel(); MappedByteBuffer mbb = ch.map(MapMode.READ_WRITE, position, mapsize); int cnt = 0; try { System.out.println("fill file by nio"); setStartT(); for (int i = 0; i < num; i++) { if(mbb.remaining() < content.getBytes().length) { cnt ++; position += mbb.position(); mbb = null; if(cnt %50 == 0) { System.gc(); System.out.println("call gc"); } mbb = ch.map(MapMode.READ_WRITE, position, mapsize); } mbb.put(content.getBytes()); } ellipseT(); } finally { if(ch != null) ch.close(); } } public static void readFile1() throws IOException { long mapsize = content.getBytes().length*1000000; long position = 0; //long rper = 2000000000; long rper = 1300000000; FileChannel ch = new RandomAccessFile(filename1,"rw").getChannel(); MappedByteBuffer mbb = ch.map(MapMode.READ_WRITE, 0, rper); int rs = 102400; byte dst[] = new byte[rs]; int cnt = 0; while(mbb.hasRemaining()) { ByteBuffer bb = mbb.get(dst); cnt ++; if(cnt %50 == 0) System.out.println(bb.toString()); } } }
4,谁然FileOutputStream也有channel功能,但是如果要用内存映射文件方式写文件,则只能使用RandomAccessFile,视乎是因为写时就有读,所以只能用它。
5, 他跟其他ByteBuffer不一样的地方,其他ByteBuffer需要用channel.write/read来写入/读取目标的数据,而MappedByteBuffer直接就是对于目标,它的修改会自动写入到磁盘中,除非你设定了PRIVATE。
6, 内存溢出问题,除了尺寸限制,在写大文件时,由于要不停的重新map,会导致内存溢出,或者说gc来不及回收内存,如上面程序,如果把prepareFile1中的
mbb = null; if(cnt %50 == 0) { System.gc(); System.out.println("call gc"); }
代码删除,则在3G左右就会报内存溢出;如果只保留mbb=null;则在5G左右报内存溢出,都保留则不报内存溢出。因此需要手工运行System.gc().
7, 对于中文读写,需要转码。
当然原来io也需要转码,不过有InputStreamReader中可以指定字符集因此可以不自己写代码。
如果不转码,则用UE等工具打开文件看到的是乱码,但是用java的MappedByteBuffer读取处理还是中文。
转码代码:
public static ByteBuffer getBytes(String str) {// 将字符转为字节(编码) Charset cs = Charset.forName("GBK"); ByteBuffer bb = ByteBuffer.wrap(str.getBytes(cs)); return bb; } public static String getChars(ByteBuffer bb) {// 将字节转为字符(解码) Charset cs = Charset.forName("GBK"); bb.flip(); CharBuffer cb = cs.decode(bb); return cb.toString(); }
发表评论
-
jstat 详解
2012-07-28 12:56 929jstat 详解 jstat ... -
NIO的内存映射文件一些问题
2012-07-28 12:51 1203见 http://yipsilon.iteye.com/bl ... -
JAVA使用HttpUrlConnection实现自动上传文件
2012-05-14 12:04 15450首先,实现自动上传文件方式有很多种,其中就有 SOCK ... -
Permanent会被GC
2012-04-23 17:27 821http://fallenlord.blogbus.c ... -
JVM内存分析工具
2011-11-28 17:17 1247参考 jvm内存分解: ... -
JVM内存解析
2011-11-28 17:10 890参考: http://vanadiumlin.iteye.c ... -
基本类型的初始化值
2011-11-28 11:05 1013各基本类型在没初始化时,默认如下值 boolean init ... -
多线程笔记
2011-11-28 10:47 8451、synchronized以线程为单位,不是以调用为单位,通 ... -
B/S系统打印
2011-11-10 17:00 1322B/S系统打印都很费劲,到目前我还没找到一个完善的方法,以下是 ... -
在文件中间插入数据
2011-11-10 15:55 1067目前没有什么好方法能直接在文件中间插入数据. 都是采用先将插 ... -
将JAR打包成EXE,并且生成安装文件
2011-11-10 15:21 2629桌面程序项目完成后,需要将项目打包成安装包在WINDOWS下运 ... -
卸载JDK导致applet不能显示
2011-11-09 17:59 898最近做测试,需要卸载JDK,卸载后发现JAVA UPDATE不 ... -
多线程下谨慎对待基类(抽象类)中的成员变量
2011-07-06 22:13 2387有这么个需求: 做开发 ... -
wait和notify使用方法
2011-07-05 13:47 1227原则是: 调用wait的对象必须是synchronized中的 ... -
SimpleDateFormat在多线程下不安全
2011-07-05 13:42 2099在工具类中有2个时间格式化和字符串转换成时间的函数,使用了类静 ... -
java计算两个日期间隔方法
2011-06-24 16:55 2818SimpleDateFormat formatter = ... -
jtable选中指定的行和选中事件监听
2011-06-16 18:49 11363选中行 table.getSelectionModel().s ... -
监听jtable单元格内容改变事件
2011-06-16 18:45 7594对话框监听jtable内容是否改变,改变后,在用户退出时提示是 ... -
自定义jtable单元格显示方式
2011-06-16 18:41 1571自定义jtable显示方式,需要继承DefaultTableC ... -
自定义jtable单元格编辑器
2011-06-16 18:35 3614jtable每行每列的单元格的编辑器都可以自定义, 方法如下: ...
相关推荐
《深入浅出MappedByteBuffer》这篇文章主要探讨了Java NIO中MappedByteBuffer这一高效处理大文件的机制,以及与其相关的计算机内存管理概念。首先,我们来详细理解一下这些知识点。 内存管理是计算机系统的重要组成...
Bug ID 4724038 (fs) Add unmap method to MappedByteBuffer
本人初学c++,写了一个小软件,能把大文件分割问小文件,然后可以统国网络传输,到了网络另一端,再用此软件拼接! 希望用过的人能提宝贵意见! 13521825644 qq 362192302
另外,内存映射文件不适合频繁的小规模写操作,因为每次写操作都会导致整个缓冲区在内存中变为脏,可能增加不必要的同步开销。 总的来说,Java的MappedByteBuffer是处理大文件的强大工具,它利用了操作系统的内存...
在Java中,可以通过`java.nio.MappedByteBuffer`类来实现共享内存功能,这被称为内存映射文件(Memory-Mapped File,MMF)。 `MappedByteBuffer`是NIO中的一种特殊缓冲区,它将文件的一部分映射到内存中,使得文件...
为了有效地读取大文件,可以使用缓冲区(Buffer)和内存映射文件(MappedByteBuffer)技术。下面将详细解释如何使用这些技术以及代码中的关键部分。 1. **缓冲区(Buffer)**: Java中的缓冲区是用于提高数据读写...
MappedByteBuffer DirectByteBuffer HeapByteBuffer ShortBuffer IntBuffer LongBuffer FloatBuffer DoubleBuffer CharBuffer Selector选择器 Selector的作用就是配合一个线程来管理多个channel,获取这些channel上...
对于需要随机访问或文件特别大的情况,推荐使用`RandomAccessFile`和`FileChannel`的组合,特别是利用`MappedByteBuffer`进行内存映射文件读取。这种方式能够显著提高文件的读取速度,因为数据直接从磁盘映射到内存...
在Java NIO中,内存映射文件(MappedByteBuffer)是一个重要的特性,它允许将文件直接映射到内存中,以便于快速访问和修改文件内容。这一特性不仅提高了读写效率,而且还能用于进程间通信(IPC)。 内存映射文件的...
在IT行业中,文件数据的处理是一项常见的任务,特别是在数据交换和存储时。"读取文件数据并解析成bean实体类"这一主题涉及到的核心知识点主要包括文件操作、数据解析以及对象映射。下面将详细阐述这些概念及其应用。...
通过MappedByteBuffer,我们可以让操作系统负责数据的缓存和页面交换,这在处理大文件时能显著降低内存使用。 在实际生产环境中,为了确保稳定性,还需要考虑错误处理和重试机制。例如,当某个线程在处理数据时发生...
本主题聚焦于Java平台下如何实现高效的文件操作,特别是利用内存映射(MappedByteBuffer)进行读写和通过网络进行文件传输。以下是相关的知识点详解: 1. **内存映射文件(MappedByteBuffer)**: 内存映射文件是...
另外,虽然 MappedByteBuffer 在逻辑上应该是 DirectByteBuffer 的子类,而且 MappedByteBuffer 的内存的 GC 和直接内存的 GC 类似(和堆 GC 不同),但是分配的 MappedByteBuffer 的大小不受 -XX:...
另外,如果文件非常大,可以考虑使用内存映射文件(`MappedByteBuffer`)或NIO(New I/O)来进一步优化性能。 以上就是用Java将一个文件拆分为多个小文件的基本步骤和相关知识点。在实际应用中,根据具体需求,可能...
- **MappedByteBuffer**:文件映射缓冲区,它允许将文件的一部分直接映射到内存,从而提供快速的文件访问。 2. **按行读取的实现**: - 类`NioReader`初始化时,创建了一个`FileInputStream`和`FileChannel`对象...
MappedByteBuffer buffer = remoteChannel.map(FileChannel.MapMode.READ_ONLY, remoteChannel.position(), blockSize); if (buffer.limit() == 0) break; localChannel.write(buffer); } // 关闭文件通道 ...
函数原型 private MappedByteBuffer mappedFile2Buffer(File f) throws Exception 函数说明 把日志文件映射成内存缓冲 参数说明 @param File f日志文件 返回说明 @return MappedByteBuffer 内存映射缓冲。 异常说明 ...
对于小文件,由于页对齐可能导致内存浪费。此外,大文件映射可能导致内存占用过高,尤其是在内存有限的环境中。因此,使用内存映射文件时应谨慎评估文件大小和系统资源。 总之,Java的内存映射文件功能为处理大文件...
FileChannel提供了map()方法,可以将文件的一部分或全部映射到Java虚拟机的内存中,形成一个MappedByteBuffer对象。这样,对MappedByteBuffer的操作实际上就是对文件的直接操作,无需频繁地进行磁盘I/O,大大提高了...
`FileChannel`提供了随机读写文件的能力,而`MappedByteBuffer`则可以将文件的一部分映射到内存,使得对文件的操作就像操作普通数组一样方便。通过比较已下载的缓冲区与目标文件的校验值,可以判断下载是否完整,...