订阅所有JSP/Servlet的日志 订阅 | 这是最新一篇日志 上一篇 | 下一篇日志 下一篇 ]
JAVA技术

MappedByteBuffer的unmap()

昨天在用NIO的MappedByteBuffer时遇到了一个Java的Bug(具体内容请看Java Bug MappedByteBuffer无unmap()一文)。
今天在网上收集了一些资料并做了测试,找出了一个较好的解决方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
public void testMappedByteBuffer() {
	int length = 10485760;
	MappedByteBuffer out = null;
	RandomAccessFile ranFile = null;
	File file = null;
                FileChannel fileChannel= null;
	try {
		file = new File("d:/test.txt");
		ranFile = new RandomAccessFile(file, "rw");
                                fileChannel = ranFile.getChannel();
		out = ranFile.getChannel().map(
		fileChannel.MapMode.READ_WRITE, 0, length);
		for (int i = 0; i < length; i++)
			out.put((byte) 'x');
		System.out.println("Finished writing");
	} catch (FileNotFoundException e) {
		e.printStackTrace();
	} catch (IOException e) {
		e.printStackTrace();
	}finally{
                    fileChannel.close();
                    ranFile.close();
                    unmap(out);
                }	
                try {
		file.delete();
		System.out.println("Delete File");
                                Thread.sleep(100000);
	} catch (Exception e) {
		e.printStackTrace();
	}
}
 
public void unmap(final Object buffer) throws Exception {
       AccessController.doPrivileged(new PrivilegedAction() {
	public Object run() {
	        try {
		Method getCleanerMethod = buffer.getClass()
                                .getMethod("cleaner", new Class[0]);
	               getCleanerMethod.setAccessible(true);
	               sun.misc.Cleaner cleaner = (sun.misc.Cleaner) 
                               getCleanerMethod.invoke(buffer, new Object[0]);
	               cleaner.clean();
	          } catch (Exception e) {
	             e.printStackTrace();
	         }
                     return null;
	  }
         });
}
 

注意:fileChannel和ranFile一定要调close()!
而对于unmap()则比较让人疑惑:很多资料上都说cleaner 这一对象只在UNIX上有效,而在Windows上是无效的,但我在两种系统环境下分别测试过,都是有效的,即程序在运行中可以删除由map写入的文件!

另一种方法:
1
2
3
4
5
6
7
8
9
finally{
        if(out != null){
                   fileChannel.close();
                   ranFile.close();
                   out.force();
                   out = null;
                   System.gc();
      }
}

但此方法在多线程并发循环(每个线程要写多个文件)执行时速度很慢,并且有时只能删除部分文件。效果不佳!

平均得分
(0 次评分)





文章来自: 本站原创
标签: MappedByteBuffer 关闭 unmap() close() 
评论: 63 | 查看次数: 1686
  • 共有 63 条评论
  • 1
  • 2
  • 3
  • 4
  • 5
  • |
  • >>
游客 [2008-12-01 22:49:34]
hhygr11jxx [2008-12-01 14:45:57]
游客 [2008-11-28 17:19:57]
游客 [2008-11-26 17:07:59]
游客 [2008-11-21 14:55:44]
游客 [2008-11-14 16:46:53]
游客 [2008-11-14 09:17:48]
游客 [2008-11-13 11:59:13]
游客 [2008-11-08 09:51:27]
游客 [2008-11-07 13:03:41]
游客 [2008-11-06 15:56:35]
游客 [2008-11-06 15:56:35]
游客 [2008-11-06 15:40:16]
游客 [2008-11-06 10:30:58]
游客 [2008-11-06 10:06:28]
  • 共有 63 条评论
  • 1
  • 2
  • 3
  • 4
  • 5
  • |
  • >>
发表评论
昵 称:  登录
内 容:
选 项:
字数限制 1000 字 | UBB代码 开启 | [img]标签 开启