读取一个日志文件,将其插入数据库,这个日志文件有2G这么大,读取的时候报Exception in thread "main" java.lang.OutOfMemoryError: Java heap space 这个异常,主要代码如下:public static void main(String[] args) { try {
FileReader fr = new FileReader(ConfigReader.getInstance().getInPath());
BufferedReader br = new BufferedReader(fr);
String line = "";
List<String> logList = new ArrayList<String>();
while (line != null) {
line = br.readLine();
if(line != null && line.length() != 0){
logList.add(line);
}
}
System.out.println("总共有:"+logList.size()+"行");
System.out.println("读取文件完成!");
LogDao_0629 ld = new LogDao_0629();
ld.addLog(DBUtil.getConnection(), logList);
System.out.println("-----插入--OK-------");
} catch (Exception e) {
e.printStackTrace();
}
}文件内容如下所示:
30.16.18.11 - - [19/Nov/2009:14:19:26 +0800] "GET /BTS_HX/ HTTP/1.1" 404 205
30.16.18.11 - - [01/Dec/2009:15:40:39 +0800] "GET /BTS_HX/ HTTP/1.1" 404 205
30.16.18.11 - - [01/Dec/2009:15:41:07 +0800] "GET /BTS_HX/ HTTP/1.1" 404 205
30.16.18.11 - - [01/Dec/2009:15:41:33 +0800] "GET /BTS_HX/ HTTP/1.1" 404 205
30.16.18.11 - - [01/Dec/2009:15:43:32 +0800] "GET /BTS_HX/ HTTP/1.1" 200 27652
30.16.18.11 - - [01/Dec/2009:15:43:43 +0800] "GET /BTS_HX/ HTTP/1.1" 404 205
现在如果使用缓存分段读取,如何写才对?

解决方案 »

  1.   

    你设置一个阈值,当logList中的字符串的个数大于阈值时就将logList保存到数据库,然后清空logList就行了吧
      

  2.   

    像这样的大文件首先用RandomAccessFile读可能效率会更好些。分段读写,可以简单的判断logList的大小,超过一个阙值就把其中的数据写入数据库,然后清空,再继续读文件。
      

  3.   

    我觉得清空list可能也不行吧?list置空后,堆内存的对象还不能自己立即释放,还是可能会溢出异常。
      

  4.   

    你不要一次将所有的数据全都add到logList里,你把2G的数据一下全塞到内存里肯定不行了。
    你读一行就处理一行,或者读几行就处理一次。 
      

  5.   

    java有垃圾回收器,之所以没释放是因为还存在引用,清了就可以了
    想要快点用数据库的bulkloader或者多线程或者nio
      

  6.   


    while (line != null) {
         line = br.readLine();
         if(line != null && line.length() != 0){
              logList.add(line);
              if(logList.size >= 100){
                   LogDao_0629 ld = new LogDao_0629();
                   ld.addLog(DBUtil.getConnection(), logList);
                   System.out.println("-----插入--OK-------");
                   logList.clear();
              }
         }
    }