【问题标题】:How does other applications handle large text files without having a large memory foot print?其他应用程序如何在不占用大量内存的情况下处理大型文本文件?
【发布时间】:2013-08-26 09:48:22
【问题描述】:

我想知道像 Bairtail 或 Baregrep 这样的应用程序如何处理如此大的文本文件而不占用大量空间?

我正在尝试在 Java 中做类似的事情:

Viewing large log files in JavaFX in a ListView

但是当我处理大型文本日志文件(900Mb 到 2.5Gb 的文本)时,我遇到了问题。当我阅读文本文件时,JVM 内存大小急剧增加。

另一种方法是只检索我感兴趣的行。但我不知道在 java 中有任何技术可以做到这一点。我必须开始逐行阅读,直到我到达我想要的所需行(比如说第 1000 行),然后抓住那个文本。但这样做时,我在内存中有 999 行等待被 GC 处理。

例如,Bairgrep 正在扫描文件夹中的多个文件并寻找模式。如果我打开任务管理器,我几乎看不到内存占用正在增长。这些程序使用什么类型的技术或扫描方式。

有没有可以在我的应用程序中使用的技术来处理大型文本文件?


我可能会补充一点,我的日志文件是由 java 应用程序生成的文件,并且每行的长度不一样。

一个更正...内存占用我的意思是我无法读取内存中的 6Gb 文件。如果我使用 -Xmx 将 VM 大小指定为较小的事件。读取 6Gb 文件时应用程序内存不足。


添加了两种我尝试从 758 Mb 日志文件中获取文本的方法

方法一

 @FXML
private void handleButtonAction(ActionEvent event) {
    final String fileName = "D:/Development/Logs/File1.log";
    try {
        BufferedReader in = new BufferedReader(new FileReader(fileName));
        while (in.ready()) {
            String s = in.readLine();
        }
        in.close();
    } catch (Exception e) {
        e.printStackTrace();
    } 
}

方法二

 @FXML
private void handleButtonAction(ActionEvent event) {
    final String fileName = "D:/Development/Logs/File1.log";        
    Scanner scan = null;
    try {            
        File file = new File(fileName);

        if (!file.exists()) {
            return;
        }
        scan = new Scanner(file);
        long start = System.nanoTime();
        while (scan.hasNextLine()) {
            final String line = scan.nextLine();                     
        }            
    } catch (Exception e) {
        e.printStackTrace();            
    } finally {
        scan.close();
    }
}

【问题讨论】:

  • “等待 GC”的数据不会增加应用程序的内存占用。如果您想减少占用空间,请使用 -Xmx 指定它。
  • @Marko-我更新了问题。我的意思是,如果我让虚拟机太小,它会在读取文件时耗尽内存。
  • 如果您的内存不足,则说明您的代码存在问题。如果您不在内存中保留较早的行,则没有理由发生 OOME。
  • 让我们看一些代码。没有理由 java 必须保留它从文件中读取的每一行。
  • 添加了使用 BufferedReader 和扫描器类的代码。这两种情况每次调用该方法时内存都会跳跃大约 200mb。

标签: java parsing java-7 large-files


【解决方案1】:

我认为“MemoryMappedFile”是您正在寻找的。​​p>

我找到了一些可以帮助您的链接: http://www.linuxtopia.org/online_books/programming_books/thinking_in_java/TIJ314_029.htm http://javarevisited.blogspot.de/2012/01/memorymapped-file-and-io-in-java.html

【讨论】:

  • 问题是我的日志文件有 1000 行可变长度的行,这使得读取行变得困难让我们在第 998-1024 行说这么多网站声明不应该使用它forums.oracle.com/thread/2072711
【解决方案2】:

您提到的两个应用程序都可能“处理”大文件,但它们实际上并不需要将整个文件加载到内存中。第一个听起来像是直接寻找文件的末尾,而第二个是逐行操作。

他们可能通过 JNI 使用本机代码来实现低内存使用。

编辑:事实上,它们看起来是纯粹的 C 或 C++ 应用程序,它们不需要像 Java 应用程序那样等待 GC

【讨论】:

  • 区别绝对不在于自动内存管理(又名 GC)。
  • 是否有第三方库可供 java 使用来执行此操作?我需要能够扫描每一行以查看它是否包含一个字符串以及读取特定行数的能力 - 比如说第 998 行到第 1024 行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-31
  • 2021-03-09
  • 2013-04-08
  • 2012-08-20
  • 2011-07-24
  • 2011-11-11
相关资源
最近更新 更多