bufferedreader或inputstreamreader中的gc开销

时间:2015-10-20 18:43:23

标签: java garbage-collection

{
    Connection connection;
    ZipFile zipFile = null;
    InputStream inputStream = null;
    BufferedReader bufferedReader = null;
    try {
        connection = ConnectionManager.getConnection();
        zipFile = new ZipFile(fileUpload);
        Enumeration<? extends ZipEntry> entries = zipFile.entries();
        ZipEntry entry;
        String line = "";
        DBBridge dbBridge = new DBBridge();
        while (entries.hasMoreElements()) {
            entry = entries.nextElement();
            boolean firstLineSkipped = false;
            boolean insertStockFlag = false;
            inputStream = zipFile.getInputStream(entry);
            Reader reader = new InputStreamReader(inputStream,"UTF-8");
            bufferedReader = new BufferedReader(reader);
            while ((line = bufferedReader.readLine()) != null) {
                String[] stockData = line.split(",");
                if (firstLineSkipped && !insertStockFlag){ 
                    dbBridge.insertStockSP(connection, stockData[0], stockData[11], stockData[12], stockData[13]);
                    insertStockFlag = true;
                }
                if(firstLineSkipped && insertStockFlag) {
                    dbBridge.insertStockDailyInfo(connection, stockData[0], stockData[1], stockData[2], stockData[3], stockData[4], stockData[5], stockData[6], stockData[7], stockData[8], stockData[9], stockData[10], stockData[14]);
                }
                firstLineSkipped = true;
            }
            reader.close();
            reader = null;
            bufferedReader.close();
            bufferedReader = null;
        }
        return SUCCESS;
    } catch (FileLockInterruptionException e) {
        return ERROR;
    } catch (IOException e) {
        return ERROR;
    } catch (ClassNotFoundException e) {
        return ERROR;
    } catch (SQLException e) {
        return ERROR;
    } catch (Exception e) {
        return ERROR;
    } finally {
        try {
            if (zipFile != null){
                zipFile.close();
                zipFile = null;
            }
            if (inputStream != null){
                inputStream.close();
                inputStream = null;
            }
            if (bufferedReader != null){
                bufferedReader.close();
                bufferedReader = null;
            }
        } catch (IOException e) {
            /* e.printStackTrace(); */
        }
    }
}

这是我在zip文件中导入一些csv文件的方法,但是我遇到了超出gc开销限制的问题。问题是由inputstreamreader的bufferedreader引起的吗?我能做什么?是什么导致了这个错误?

修改:这是insertStockSP

中的DBBridge
    public void insertStockSP(Connection connection,String symbolName, String Code, String latinName, String persianName) throws SQLException {
    CallableStatement proc = connection.prepareCall("{call insertStock(?,?,?,?)}");
    proc.setString(1, symbolName);
    proc.setString(2, Code);
    proc.setString(3, latinName);
    proc.setString(4, persianName);
    proc.execute();
}

我不认为问题是这样的。 insertStockDailyInfo就是这样。

Exception in thread "ContainerBackgroundProcessor[StandardEngine[Catalina]]" java.lang.OutOfMemoryError: GC overhead limit exceeded
at java.lang.AbstractStringBuilder.<init>(AbstractStringBuilder.java:64)
at java.lang.StringBuffer.<init>(StringBuffer.java:108)
at java.io.Win32FileSystem.normalize(Win32FileSystem.java:122)
at java.io.Win32FileSystem.normalize(Win32FileSystem.java:189)
at java.io.File.<init>(File.java:367)
at org.apache.naming.resources.FileDirContext.file(FileDirContext.java:765)
at org.apache.naming.resources.FileDirContext.doGetAttributes(FileDirContext.java:398)
at org.apache.naming.resources.BaseDirContext.getAttributes(BaseDirContext.java:1137)
at org.apache.naming.resources.BaseDirContext.getAttributes(BaseDirContext.java:1090)
at org.apache.naming.resources.ProxyDirContext.getAttributes(ProxyDirContext.java:882)
at org.apache.catalina.loader.WebappClassLoader.modified(WebappClassLoader.java:1026)
at org.apache.catalina.loader.WebappLoader.modified(WebappLoader.java:500)
at org.apache.catalina.loader.WebappLoader.backgroundProcess(WebappLoader.java:420)
at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1345)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1530)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1540)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1540)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1519)
at java.lang.Thread.run(Thread.java:724)
Exception in thread "http-bio-8080-exec-1" java.lang.OutOfMemoryError: GC overhead limit exceeded
at java.util.jar.Attributes.read(Attributes.java:394)
at java.util.jar.Manifest.read(Manifest.java:199)
at java.util.jar.Manifest.<init>(Manifest.java:69)
at java.util.jar.JarFile.getManifestFromReference(JarFile.java:180)
at java.util.jar.JarFile.getManifest(JarFile.java:166)
at org.apache.catalina.loader.WebappClassLoader.findResourceInternal(WebappClassLoader.java:3135)
at org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:2892)
at org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:1210)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1690)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1571)
at com.opensymphony.xwork2.util.logging.commons.CommonsLogger.error(CommonsLogger.java:38)
at org.apache.struts2.dispatcher.Dispatcher.sendError(Dispatcher.java:903)
at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:574)
at org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:99)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:724)

这是堆栈跟踪,我不得不说我使用Struts 2。

1 个答案:

答案 0 :(得分:0)

以下是关于潜在的不足/问题的几点想法:

1)为什么不使用ZipInputStream而不是ZipFile,因为您不需要随机访问文件中间的内部条目 http://www.java2s.com/Tutorial/Java/0180__File/UnzipusingtheZipInputStream.htm

2)我建议你检查文件扩展名,以确保你处理包含相对较短行的文本文件。可能会发生从二进制文件中逐行读取可能导致内部垃圾装入内存中的长字符串。

3)dbBridge的方法可能会导致内存泄漏。