学习啦>学习电脑>电脑硬件知识>内存知识>

java读取大文件内存溢出怎么解决

时间: 东浩765 分享

  java读取大文件内存溢出问题、如何在不重复读取与不耗尽内存的情况下处理大文件怎么办?别怕,下面就由学习啦小编为大家整理的解决办法,供大家参考!

  相关的Java解决方法:

  1、传统的在内存中读取

  读取文件行的标准方式是在内存中读取,Guava 和Apache Commons IO都提供了如下所示快速读取文件行的方法:

1 2 3Files.readLines(newFile(path), Charsets.UTF_8);FileUtils.readLines(newFile(path));

  这种方法带来的问题是文件的所有行都被存放在内存中,当文件足够大时很快就会导致程序抛出OutOfMemoryError 异常。

  例如:读取一个大约1G的文件:

1 2 3 4 5@TestpublicvoidgivenUsingGuava_whenIteratingAFile_thenWorks()throwsIOException {String path = ...Files.readLines(newFile(path), Charsets.UTF_8);}

  这种方式开始时只占用很少的内存:(大约消耗了0Mb内存)

1 2[main] INFO org.baeldung.java.CoreJavaIoUnitTest - Total Memory:128Mb[main] INFO org.baeldung.java.CoreJavaIoUnitTest - Free Memory:116Mb

  然而,当文件全部读到内存中后,我们最后可以看到(大约消耗了2GB内存):

1 2[main] INFO org.baeldung.java.CoreJavaIoUnitTest - Total Memory:2666Mb[main] INFO org.baeldung.java.CoreJavaIoUnitTest - Free Memory:490Mb

  这意味这一过程大约耗费了2.1GB的内存——原因很简单:现在文件的所有行都被存储在内存中。

  把文件所有的内容都放在内存中很快会耗尽可用内存——不论实际可用内存有多大,这点是显而易见的。

  此外,我们通常不需要把文件的所有行一次性地放入内存中——相反,我们只需要遍历文件的每一行,然后做相应的处理,处理完之后把它扔掉。所以,这正是我们将要做的——通过行迭代,而不是把所有行都放在内存中。

  2、文件流

  现在让我们看下这种解决方案——我们将使用java.util.Scanner类扫描文件的内容,一行一行连续地读取:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21FileInputStream inputStream =null;Scanner sc =null;try{inputStream =newFileInputStream(path);sc =newScanner(inputStream,UTF-8);while(sc.hasNextLine()) {String line = sc.nextLine();// System.out.println(line);}// note that Scanner suppresses exceptionsif(sc.ioException() !=null) {throwsc.ioException();}}finally{if(inputStream !=null) {inputStream.close();}if(sc !=null) {sc.close();}}

  这种方案将会遍历文件中的所有行——允许对每一行进行处理,而不保持对它的引用。总之没有把它们存放在内存中:(大约消耗了150MB内存)

1 2[main] INFO org.baeldung.java.CoreJavaIoUnitTest - Total Memory:763Mb[main] INFO org.baeldung.java.CoreJavaIoUnitTest - Free Memory:605Mb

  3、Apache Commons IO流

  同样也可以使用Commons IO库实现,利用该库提供的自定义LineIterator:

1 2 3 4 5 6 7 8 9LineIterator it = FileUtils.lineIterator(theFile,UTF-8);try{while(it.hasNext()) {String line = it.nextLine();// do something with line}}finally{LineIterator.closeQuietly(it);}

  由于整个文件不是全部存放在内存中,这也就导致相当保守的内存消耗:(大约消耗了150MB内存)

1 2[main] INFO o.b.java.CoreJavaIoIntegrationTest - Total Memory:752Mb[main] INFO o.b.java.CoreJavaIoIntegrationTest - Free Memory:564Mb

  4、结论

  这篇短文介绍了如何在不重复读取与不耗尽内存的情况下处理大文件——这为大文件的处理提供了一个有用的解决办法。

java读取大文件内存溢出怎么解决

java读取大文件内存溢出问题、如何在不重复读取与不耗尽内存的情况下处理大文件怎么办?别怕,下面就由学习啦小编为大家整理的解决办法,供大家参考! 相关的Java解决方法: 1、传统的在内存中读取 读取文件行的标准方式是在内存中读取,Gu
推荐度:
点击下载文档文档为doc格式

精选文章

  • java多线程内存模型
    java多线程内存模型

    Java虚拟机规范中试图定义一种Java内存模型(Java Memory Model,JMM)来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的

  • java如何手动释放内存
    java如何手动释放内存

    Java是由Sun Microsystems公司推出的Java面向对象程序设计语言(以下简称Java语言)和Java平台的总称。 Java由James Gosling和同事们共同研发,并在1995年正式推出。J

  • i苹果助手怎么清理内存
    i苹果助手怎么清理内存

    或许有很多人在使用i苹果助手时常常遇到不知道怎么清理内存,今天就由学习啦小编来教大家怎么清理吧! 清理i苹果助手的步骤: 设置----通用------用量,

  • iphone怎么删内存
    iphone怎么删内存

    今天学习啦小编和大家分享几个iPhone6内存清理方法教程,教大家如何快速释放iPhone6内存的解决方法,如果你觉得自己的手机使用时间长了,变得卡了、慢

580016