我编写了一个应用程序,该应用程序在其模块之一中解析巨大的文件,并将此文件逐块保存到数据库中。
首先,下面的代码有效,我的主要问题是减少内存使用并总体上提高性能。
以下代码段只是一小部分,但在进行一些YourKit分析后,这是最成问题的。用/ * 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"));
....
可以分配大量的内存,因为String很大(我也需要这么大的块),这是可以接受的。我的主要问题是,由于getBytes的结果,同一分配发生两次,
因此,我的问题是他们是否可以将findWithinHorizon Result直接传输到InputStream而无需两次分配内存?
它们是实现相同功能的更有效方法吗?
最佳答案
不是完全相同的方法,而是尝试使用findWithinHorizon
代替,您可以尝试读取每行并在行上下文中搜索模式。这肯定会减轻内存压力,因为您不会像API所述那样缓冲整个文件:
如果地平线为0,则地平线被忽略,此方法继续
搜索输入以查找指定的模式而无需
界。在这种情况下,它可能会缓冲所有搜索
图案。
就像是:
while(String line = fileScanner.nextLine() != null) {
if(grep for pattern in line) {
}
}