randomaccessfile详解造成内存泄漏怎么关闭

Java输入输出流详细用法_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
Java输入输出流详细用法
上传于|0|0|暂无简介
阅读已结束,如果下载本文需要使用5下载券
想免费下载本文?
定制HR最喜欢的简历
下载文档到电脑,查找使用更方便
还剩6页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢尽管从JDK 1.4版本开始,Java内存映射文件(Memory Mapped Files)就已经在java.nio包中,但它对很多程序开发者来说仍然是一个相当新的概念。引入NIO后,Java IO已经相当快,而且内存映射文件提供了Java有可能达到的最快IO操作,这也是为什么那些高性能Java应用应该使用内存映射文件来持久化数据。这在一些交易非常频繁的场合已经应用得很多,这些场合要求电子交易系统必须非常快速,单向时延要小于毫秒级。IO一直是那些高性能系统的一个主要关注点,内存映射文件允许你使用direct或者non-direct 字节缓存(Byte buffer)来直接读写内存。内存映射文件的一个关键优势是操作系统负责真正的读写,即使你的程序在刚刚写入内存后就挂了,操作系统仍然会将内存中的数据写入文件系统。另外一个更突出的优势是共享内存,内存映射文件可以被多个进程同时访问,起到一种低时延共享内存的作用。
什么是Java内存映射文件/IO
内存映射文件是一种允许Java程序直接从内存访问的特殊文件。通过将整个文件或者文件的一部分映射到内存中、操作系统负责获取页面请求和写入文件,应用程序就只需要处理内存数据,这样可以实现非常快速的IO操作。用于内存映射文件的内存在Java的堆空间以外。Java中的java.nio包支持内存映射文件,可以使用MappedByteBuffer来读写内存。
内存映射文件的优缺点
可能内存映射IO的主要优势是性能,内存映射文件比通过普通的IO来访问文件要快,这对于繁忙的电子交易系统来说非常重要。内存映射IO另外一个优势是能够加载普通方式无法访问的大文件,实验表明内存映射IO在大文件处理中表现得更好;但缺点是有增加页面错误(page fault)的可能,因为操作系统仅仅加载一部分文件到内存中,如果被请求的页面不在内存中那就会导致一个页面错误。大多数主流操作系统如Windows, Unix, Solaris和其他类Unix的操作系统都支持内存映射IO,在64位架构下,你几乎可以将任何文件映射到内存中并直接使用Java访问。另外一个优势是这些文件能够共享,在进程间提供共享内存,而且比普通的基于loopback接口的Socket要快10倍。
Java中MappedByteBuffer读写样例
下面的例子演示了如何使用内存映射文件来读写。我们使用RandomAccessFile打开文件并使用FileChannel的map()方法将它映射到内存,map()方法有三个输入参数:mode, position, size。返回值MappedByteBuffer是用来处理内存映射文件的字节缓存。
import java.io.RandomAccessF
import java.nio.MappedByteB
import java.nio.channels.FileC
public class MemoryMappedFileInJava {
private static int count = ; // 10 MB
public static void main(String[] args) throws Exception {
RandomAccessFile memoryMappedFile = new RandomAccessFile(&largeFile.txt&, &rw&);
// Mapping a file into memory
MappedByteBuffer out = memoryMappedFile.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, count);
// Writing into Memory Mapped File
for (int i = 0; i & i++) {
out.put((byte) &A&);
System.out.println(&Writing to Memory Mapped File is completed&);
// reading from memory file in Java
for (int i = 0; i & 10; i++) {
System.out.print((char) out.get(i));
System.out.println(&Reading from Memory Mapped File is completed&);
memoryMappedFile.close();
下面快速总结一下Java内存映射文件和IO
1). Java语言通过java.nio包支持内存映射文件和IO。
2). 内存映射文件用于对性能要求高的系统中,如繁忙的电子交易系统
3). 使用内存映射IO你可以将文件的一部分加载到内存中
4). 如果被请求的页面不在内存中,内存映射文件会导致页面错误
5). 将一个文件区间映射到内存中的能力取决于内存的可寻址范围。在32位机器中,不能超过4GB,即2^32比特。
6). Java中的内存映射文件比流IO要快(译注:对于大文件而言是对的,小文件则未必)
7). 用于加载文件的内存在Java的堆内存之外,存在于共享内存中,允许两个不同进程访问文件。顺便说一下,这依赖于你用的是direct还是non-direct字节缓存。
8). 读写内存映射文件是操作系统来负责的,因此,即使你的Java程序在写入内存后就挂掉了,只要操作系统工作正常,数据就会写入磁盘。
9). Direct字节缓存比non-direct字节缓存性能要好
10). 不要经常调用MappedByteBuffer.force()方法,这个方法强制操作系统将内存中的内容写入硬盘,所以如果你在每次写内存映射文件后都调用force()方法,你就不能真正从内存映射文件中获益,而是跟disk IO差不多。
11). 如果电源故障或者主机瘫痪,有可能内存映射文件还没有写入磁盘,意味着可能会丢失一些关键数据。
12). MappedByteBuffer和文件映射在缓存被GC之前都是有效的。sun.misc.Cleaner可能是清除内存映射文件的唯一选择。
关于Java内存映射文件和内存映射IO就说这些了。 这相当有用,我希望你能够再深入了解一些。如果你的工作与繁忙的电子交易系统有关,那你很可能用到内存映射文件。
原文链接:http://javarevisited.blogspot.hk/2012/01/memorymapped-file-and-io-in-java.html
相关 [java 内存 映射] 推荐:
- 编程语言 - ITeye博客
尽管从JDK 1.4版本开始,Java内存映射文件(Memory Mapped Files)就已经在java.nio包中,但它对很多程序开发者来说仍然是一个相当新的概念. 引入NIO后,Java IO已经相当快,而且内存映射文件提供了Java有可能达到的最快IO操作,这也是为什么那些高性能Java应用应该使用内存映射文件来持久化数据.
- ITeye博客
堆(Heap)又被称为:优先队列(Priority Queue),是计算机科学中一类特殊的数据结构的统称. 堆通常是一个可以被看做一棵树的数组对象. 在队列中,调度程序反复提取队列中第一个作业并运行,因而实际情况中某些时间较短的任务将等待很长时间才能结束,或者某些不短小,但具有重要性的作业,同样应当具有优先权.
- Java - 编程语言 - ITeye博客
(问题一:什么叫垃圾回收机制. ) 垃圾回收是一种动态存储管理技术,它自动地释放不再被程序引用的对象,按照特定的垃圾收集算法来实现资源自动回收的功能. 当一个对象不再被引用的时候,内存回收它占领的空间,以便空间被后来的新对象使用,以免造成内存泄露. (问题二:java的垃圾回收有什么特点. ) JAVA语言不允许程序员直接控制内存空间的使用.
- 编程语言 - ITeye博客
不论哪种语言的内存分配方式,都需要返回所分配内存的真实地址,也就是返回一个指针到内存块的首地址. Java中对象是采用new或者反射的方法创建的,这些对象的创建都是在堆(Heap)中分配的,所有对象的回收都是由Java虚拟机通过垃圾回收机制完成的. GC为了能够正确释放对象,会监控每个对象的运行状况,对他们的申请、引用、被引用、赋值等状况进行监控,Java会使用有向图的方法进行管理内存,实时监控对象是否可以达到,如果不可到达,则就将其回收,这样也可以消除引用循环的问题.
- CSDN博客编程语言推荐文章
Linux从内核2.6开始使用NPTL (Native POSIX Thread Library)支持,但这时线程本质上还轻量级进程. Java里的线程是由JVM来管理的,它如何对应到操作系统的线程是由JVM的实现来确定的. Linux 2.6上的HotSpot使用了NPTL机制,
JVM线程跟内核轻量级进程有一一对应的关系.
- ITeye博客
JAVA的垃圾回收机制,让许多程序员觉得内存管理不是很重要,但是内存内存泄露的事情恰恰这样的疏忽而发生,特别是对于Android开发,内存管理更为重要,养成良好的习惯,有利于避免内存的泄漏..
这里可以把许多对象和引用看成是有向图,顶点可以是对象也可以是引用,引用关系就是有向边.
- ITeye博客
昨天中午,发了一篇
equals和==区别的博文,晚上再看时有几位大牛指出了其中的一些错误,很感谢他们的留言,一句简简单单的留言给了我对这些错误知识点改正的机会. 或许这就是从事互联网行业所提倡的互帮互助的精神吧,因为有分享,有交流,互联网才会发展的如此迅猛. 大牛提的一个观点很好,好的东西可以拿出来分享,错的东西却可能带给别人错误的理解,这一点我确实得向看了我写了一些bug博客的人道个歉.
- 码蜂笔记
JMM,Java Memory Model,Java 内存模型. 什么是内存模型,要他何用. 假定一个线程为变量var赋值:
var = 3;,内存模型要回答的问题是:在什么条件下,读取变量var的线程可以看到
3这个值. 如果缺少了同步,线程可能无法看到其他线程操作的结果. 导致这种情况的原因可以有:编译器生成指令的次序可以不同于源代码的“显然”版本,编译器还会把变量存储在寄存器而不是内存中;处理器可以乱序或并行执行指令;缓存会改变写入提交到主存得到变量的次序;存储在处理器本地缓存中的变量对其他处理器不可见 等等.
- ImportNew
你可以在网上找到一大堆资料让你了解JMM是什么东西,但大多在你看完后仍然会有很多疑问. happen-before是怎么工作的呢. 用volatile会导致缓存的丢弃吗. 为什么我们从一开始就需要内存模型. 通过这篇文章,读者可以学习到足以回答以上所有问题的知识. 它包含两大部分:第一部分是硬件层次的大体架构,第二部分是深入OpenJdk源代码和实现.
- Java译站
Java有垃圾回收,因此不会出现内存泄露. 尽管Java的确有垃圾回收器来回收那些不用的内存块,但你不要指望它能够点铁成金. GC减轻了开发人员肩上的负担,而原本的那些工作非常容易出错,不过并不是所有内存分配的问题它都能够解决. 更糟糕的是,Java的设计允许它可以欺骗GC,使得它能够保留一些程序已经不再使用的内存.
坚持分享优质有趣的原创文章,并保留作者信息和版权声明,任何问题请联系:@。hadoop启动遇到的各种问题
1. HDFS initialized but not 'healthy' yet, waiting...
这个日志会在启动hadoop的时候在JobTracker的log日志文件中出现,在这里就是hdfs出现问题,导致DataNode无法启动,这里唯一的解决方式就是把所有的NameNode管理的路径下的文件删除然后重新执行namenode -format,而删除的地方主要有存放临时数据的tmp路径,存放数据的data路径还有name路径,全部删除之后重新format次问题就解决了
2. 在执行hadoop程序的时候出现Name node is in safe mode
这个异常一般就直接会在IDE的控制台输出,这个错误的主要导致原因是,datanode不停在丢失数据,所以此时namenode就强制本身进入safe mode模式,在该模式下对数据只可以进行读操作而不能进行写操作。解决此异常很简单,直接执行命令让namenode离开次模式就可以了。
./hadoop dfsadmin-safemode leave
3. java.io.FileNotFoundException: /data/dfs/namesecondary/in_use.lock (Permission denied):
10:18:42,902 INFO org.apache.hadoop.metrics2.impl.MetricsSystemImpl: SecondaryNameNode metrics system started
10:18:43,053 FATAL org.apache.hadoop.hdfs.server.namenode.SecondaryNameNode: Failed to start secondary namenode
java.io.FileNotFoundException: /data/dfs/namesecondary/in_use.lock (Permission denied)
at java.io.RandomAccessFile.open0(Native Method)
at java.io.RandomAccessFile.open(RandomAccessFile.java:316)
at java.io.RandomAccessFile.&init&(RandomAccessFile.java:243)
at org.apache.hadoop.mon.Storage$StorageDirectory.tryLock(Storage.java:706)
at org.apache.hadoop.mon.Storage$StorageDirectory.lock(Storage.java:678)
at org.apache.hadoop.mon.Storage$StorageDirectory.analyzeStorage(Storage.java:499)
at org.apache.hadoop.hdfs.server.namenode.SecondaryNameNode$CheckpointStorage.recoverCreate(SecondaryNameNode.java:962)
at org.apache.hadoop.hdfs.server.namenode.SecondaryNameNode.initialize(SecondaryNameNode.java:243)
at org.apache.hadoop.hdfs.server.namenode.SecondaryNameNode.&init&(SecondaryNameNode.java:192)
at org.apache.hadoop.hdfs.server.namenode.SecondaryNameNode.main(SecondaryNameNode.java:671)
10:18:43,056 INFO org.apache.hadoop.util.ExitUtil: Exiting with status 1
10:18:43,057 INFO org.apache.hadoop.hdfs.server.namenode.SecondaryNameNode: SHUTDOWN_MSG:
/************************************************************
SHUTDOWN_MSG: Shutting down SecondaryNameNode at joyven/192.168.2.35
************************************************************
这有两种场景出现,
1):在原来正常的时候,有一次突然使用了原来不同的用户启动了一次hadoop。这种场景会产生一个in_use.lock 文件夹在你设置的目录中,这时候可以删除这个文件夹直接,然后重新启动
2):在格式化hadoop的时候和当期启动的用户不是同一个,也会导致该问题。这个时候可以使用格式化hadoop的那个用户重新启动hadoop。也可以解决此错误。
4. hadoop /tmp/mapred/ could only be replicated to 0 nodes, instead of 1
启动了集群之后发现namenode起来了,但是各个slave节点的datanode却都没起起来。去看namenode日志发现错误日志:
INFO org.apache.hadoop.ipc.Server: IPC Server handler 1 on 9000, call addBlock(/opt/hadoop/tmp/mapred/, DFSClient_) from 127.0.0.1:2278: error: java.io.IOException: File /opt/hadoop/tmp/mapred/ could only be replicated to 0 nodes, instead of 1
java.io.IOException: File /opt/hadoop/tmp/mapred/ could only be replicated to 0 nodes, instead of 1
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.getAdditionalBlock(FSNamesystem.java:1271)
at org.apache.hadoop.hdfs.server.namenode.NameNode.addBlock(NameNode.java:422)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.hadoop.ipc.RPC$Server.call(RPC.java:508)
at org.apache.hadoop.ipc.Server$Handler$1.run(Server.java:959)
at org.apache.hadoop.ipc.Server$Handler$1.run(Server.java:955)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:396)
at org.apache.hadoop.ipc.Server$Handler.run(Server.java:953)
具体原因还不是很清楚,当防火墙不关闭的时候可能出现,但是当异常宕掉整个系统再重启的时候也会出现。解决办法是master和slave同时重新格式化
5. ERROR mapred.JvmManager: Caught Throwable in JVMRunner. Aborting TaskTracker.
java.lang.OutOfMemoryError: unable to create new native thread
在运行任务的过程中,计算突然停止,去计算节点查看TaskTracker日志,发现在计算的过程中抛出以上错误,经查证是因为你的作业打开的文件个数超过系统设置一个进程可以打开的文件的个数的上限。更改/etc/security/limits.conf的配置加入如下配置
hadoop soft nproc 10000
hadoop hard nproc 64000
6. namenode 异常
14:10:08,946 INFO org.apache.hadoop.mon.Storage: Cannot access storage directory /var/lib/hadoop/cache/hadoop/dfs/name
14:10:08,947 ERROR org.apache.hadoop.hdfs.server.namenode.FSNamesystem: FSNamesystem initialization failed.
org.apache.hadoop.mon.InconsistentFSStateException: Directory /var/lib/hadoop/cache/hadoop/dfs/name is in an inconsistent state: storage directory does not exist or is not accessible.
at org.apache.hadoop.hdfs.server.namenode.FSImage.recoverTransitionRead(FSImage.java:316)
at org.apache.hadoop.hdfs.server.namenode.FSDirectory.loadFSImage(FSDirectory.java:104)
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.initialize(FSNamesystem.java:427)
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.&init&(FSNamesystem.java:388)
at org.apache.hadoop.hdfs.server.namenode.NameNode.initialize(NameNode.java:277)
at org.apache.hadoop.hdfs.server.namenode.NameNode.&init&(NameNode.java:497)
at org.apache.hadoop.hdfs.server.namenode.NameNode.createNameNode(NameNode.java:1298)
at org.apache.hadoop.hdfs.server.namenode.NameNode.main(NameNode.java:1307)
14:10:08,948 ERROR org.apache.hadoop.hdfs.server.namenode.NameNode: org.apache.hadoop.mon.InconsistentFSStateException: Directory /var/lib/hadoop/cache/hadoop/dfs/name is in an inconsistent state: storage directory does not exist or is not accessible.
at org.apache.hadoop.hdfs.server.namenode.FSImage.recoverTransitionRead(FSImage.java:316)
at org.apache.hadoop.hdfs.server.namenode.FSDirectory.loadFSImage(FSDirectory.java:104)
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.initialize(FSNamesystem.java:427)
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.&init&(FSNamesystem.java:388)
at org.apache.hadoop.hdfs.server.namenode.NameNode.initialize(NameNode.java:277)
at org.apache.hadoop.hdfs.server.namenode.NameNode.&init&(NameNode.java:497)
at org.apache.hadoop.hdfs.server.namenode.NameNode.createNameNode(NameNode.java:1298)
at org.apache.hadoop.hdfs.server.namenode.NameNode.main(NameNode.java:1307)
7. namenode无法启动(或者SecondaryNameNode无法启动)
查看namenode日志,发现端口被占用:
10:18:08,547 INFO org.apache.hadoop.http.HttpServer2: HttpServer.start() threw a non Bind IOException
java.net.BindException: Port in use: 0.0.0.0:50070
at org.apache.hadoop.http.HttpServer2.openListeners(HttpServer2.java:919)
at org.apache.hadoop.http.HttpServer2.start(HttpServer2.java:856)
at org.apache.hadoop.hdfs.server.namenode.NameNodeHttpServer.start(NameNodeHttpServer.java:142)
at org.apache.hadoop.hdfs.server.namenode.NameNode.startHttpServer(NameNode.java:752)
at org.apache.hadoop.hdfs.server.namenode.NameNode.initialize(NameNode.java:638)
at org.apache.hadoop.hdfs.server.namenode.NameNode.&init&(NameNode.java:811)
at org.apache.hadoop.hdfs.server.namenode.NameNode.&init&(NameNode.java:795)
at org.apache.hadoop.hdfs.server.namenode.NameNode.createNameNode(NameNode.java:1488)
at org.apache.hadoop.hdfs.server.namenode.NameNode.main(NameNode.java:1554)
Caused by: java.net.BindException: Address already in use
at sun.nio.ch.Net.bind0(Native Method)
at sun.nio.ch.Net.bind(Net.java:433)
at sun.nio.ch.Net.bind(Net.java:425)
at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:223)
at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
at org.mortbay.jetty.nio.SelectChannelConnector.open(SelectChannelConnector.java:216)
at org.apache.hadoop.http.HttpServer2.openListeners(HttpServer2.java:914)
... 8 more
10:18:08,550 INFO org.apache.hadoop.metrics2.impl.MetricsSystemImpl: Stopping NameNode metrics system...
10:18:08,550 INFO org.apache.hadoop.metrics2.impl.MetricsSystemImpl: NameNode metrics system stopped.
10:18:08,550 INFO org.apache.hadoop.metrics2.impl.MetricsSystemImpl: NameNode metrics system shutdown complete.
10:18:08,551 ERROR org.apache.hadoop.hdfs.server.namenode.NameNode: Failed to start namenode.
java.net.BindException: Port in use: 0.0.0.0:50070
at org.apache.hadoop.http.HttpServer2.openListeners(HttpServer2.java:919)
at org.apache.hadoop.http.HttpServer2.start(HttpServer2.java:856)
at org.apache.hadoop.hdfs.server.namenode.NameNodeHttpServer.start(NameNodeHttpServer.java:142)
at org.apache.hadoop.hdfs.server.namenode.NameNode.startHttpServer(NameNode.java:752)
at org.apache.hadoop.hdfs.server.namenode.NameNode.initialize(NameNode.java:638)
at org.apache.hadoop.hdfs.server.namenode.NameNode.&init&(NameNode.java:811)
at org.apache.hadoop.hdfs.server.namenode.NameNode.&init&(NameNode.java:795)
at org.apache.hadoop.hdfs.server.namenode.NameNode.createNameNode(NameNode.java:1488)
at org.apache.hadoop.hdfs.server.namenode.NameNode.main(NameNode.java:1554)
Caused by: java.net.BindException: Address already in use
at sun.nio.ch.Net.bind0(Native Method)
at sun.nio.ch.Net.bind(Net.java:433)
at sun.nio.ch.Net.bind(Net.java:425)
at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:223)
at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
at org.mortbay.jetty.nio.SelectChannelConnector.open(SelectChannelConnector.java:216)
at org.apache.hadoop.http.HttpServer2.openListeners(HttpServer2.java:914)
... 8 more
10:18:08,552 INFO org.apache.hadoop.util.ExitUtil: Exiting with status 1
10:18:08,553 INFO org.apache.hadoop.hdfs.server.namenode.NameNode: SHUTDOWN_MSG:
/************************************************************
SHUTDOWN_MSG: Shutting down NameNode at joyven/192.168.2.35
************************************************************/
解决方法:
既然知道是哪个端口被占用了,要么换端口要么杀掉。
mac下杀掉端口的方法:
sudo lsof -i:端口 -P
sudo kill -9 PID
以50070端口为例:
sudo lsof -i:50070 -P
控制台输出内容:
DEVICE SIZE/OFF NODE NAME
IPv4 0x782e
TCP *:50070 (LISTEN)
然后kill掉:
sudo kill -9 6501
8. NameNode、SecondaryNameNode以及DataNode无法启动的原因归纳
SecondaryNameNode
的错误大多数由于配置引起,比如core-site.xml的配置以及hdfs-site.xml的配置,涉及到ip和端口。
查看日志位于logs下的后缀部分为nameode.log以及ssecondarynamenode.log文件,一般错误写的很明显。
启动错误一般是由于data的数据存放路径配置错误,格式化错误造成。主要配置文件为core-site.xml,
hadoop.tmp.dir
属性为数据存放路径。
namenode格式化命令:
hadoop namenode -format
注:部分参考内容来源:
,请尊重原作者的劳动成果!
关注下,有惊喜!微信搜索公众号:meitianyixi
扫一扫有惊喜}

我要回帖

更多关于 randomaccessfile api 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信