【问题标题】:Java large String returned from findWithinHorizon converted to InputStream从 findWithinHorizo​​n 返回的 Java 大字符串转换为 InputStream
【发布时间】:2013-01-04 22:02:43
【问题描述】:

我写了一个应用程序,它在它的一个模块中解析大文件并将这个文件逐块保存到数据库中。

首先,以下代码可以工作,我的主要问题是减少内存使用并总体提高性能。

以下代码sn-p是大图的一小部分,但是在做了一些YourKit profiling之后问题最大, /*Here*/ 标记的行分配了大量内存。

....
Scanner fileScanner = new Scanner(file,"UTF-8");
String scannedFarm;
try{

    Pattern p = Pattern.compile("(?:^.++$(?:\\r?+\\n)?+){2,100000}+",Pattern.MULTILINE);
    String [] tableName = null;

/*HERE*/while((scannedFarm = fileScanner.findWithinHorizon(p, 0)) != null){
         boolean continuePrevStream = false;
         Scanner scanner = new Scanner(scannedFarm);

         String[] tmpTableName  = scanner.nextLine().split(getSeparator());
         if (tmpTableName.length==2){
             tableName = tmpTableName;
         }else{
             if (tableName==null){
                 continue;
             }
             continuePrevStream = true;
         }
         scanner.close();

/*HERE*/ InputStream is = new ByteArrayInputStream(scannedFarm.getBytes("UTF-8"));
....

分配大量内存是可以接受的,因为字符串很大(我也需要这么大的块),我的主要问题是 getBytes 导致相同的分配发生两次,

  1. 所以我的问题是他们有一种方法可以将 findWithinHorizo​​n 结果直接传输到 InputStream 而无需两次分配内存?

  2. 他们是否有更有效的方式来实现相同的功能?

【问题讨论】:

    标签: java memory-management inputstream java.util.scanner


    【解决方案1】:

    不完全相同的方法,但不是findWithinHorizon,您可以尝试阅读每一行并在行上下文中搜索模式。这肯定会减少内存压力,因为您不会像 API 所述那样缓冲整个文件:

    如果horizo​​n为0,那么horizo​​n被忽略,这个方法继续 搜索输入寻找指定的模式,而不 边界。 在这种情况下,它可能会缓冲所有搜索的输入 模式

    类似:

    while(String line = fileScanner.nextLine() != null) { 
       if(grep for pattern in line) { 
    
       }
    }
    

    【讨论】:

    • 缓冲输入没有限制和退避是意图,逐行处理要慢得多且不必要,因为所有行都需要作为单个块发送到数据库并且行之间不需要处理,这个输入流作为一个块发送到 LOAD DATA 语句中,较小的块将导致 LOAD DATA 无效(正如我所提到的,大块是故意的)
    • 我明白了。那时我真的看不到这个。您是否逐行分析方法?当你缓冲整个文件时,你的堆有多大?
    • 堆消耗约为 1 GB,行处理的时间性能无法接受。
    猜你喜欢
    • 1970-01-01
    • 2012-05-29
    • 2018-11-05
    • 2018-05-29
    • 2017-07-28
    • 2013-08-31
    • 2010-12-18
    • 2010-10-21
    相关资源
    最近更新 更多