Java SSH递归下载导致内存泄漏

时间:2016-01-20 12:33:08

标签: java recursion memory-management ssh memory-leaks

我正在使用JSch提供一个实用程序来备份我公司的整个服务器数据。

使用Java 8& JavaFX 2

我的问题是我相信我的递归下载是错误的,因为我的程序RAM使用率在第二天增长,似乎永远不会释放。

这是我执行的操作的顺序:

  1. 连接到远程服务器:确定;
  2. Opning SFT Channel - > session.openChannel("sftp"):好的
  3. 检索本地目录 - > sftpChannel.cd(MAIN_DIRECTORY):好的
  4. 列出目录内容 - &gt; final Vector<ChannelSftp.LsEntry> entries= sftpChannel.ls(".");
  5. 调用递归方法:
    • if (entry.getAttrs().isDir()) - &GT;调用递归方法
    • 其他 - &gt;这是一个文件,没有更多的子文件夹可以去;
    • 流程下载
  6. 现在,我认为下载部分发生了内存泄漏:

    1. 开始下载&amp;检索输入流
        

      final InputStream = sftpChannel.get(remoteFilePath,new SftpProgressMonitor());

    2. 其中SftpProgressMonitor()是提供进度监控的界面,我用它来更新UI(进度条)。此接口从不在内部引用输入流只是为了清楚说明。但它仍然是一个非静态的匿名类,因此它确实包含对DownloadMethod范围的引用。

      1. 在下载时,我创建要保存的文件并打开 OutputStream 以将下载的内容写入其中:

          

        final BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(fileToSave));

      2. 这是我在下载远程文件时写入文件的地方:

      3. 代码:

        int readCount;
            final byte[] buffer = new byte[8 * 1024];
            while ((readCount = is.read(buffer)) > 0) {
                bos.write(buffer, 0, readCount);
                bos.flush();
            }
        

        当然,一旦完成,我不会忘记关闭两个流

        is.close(); //the inputstream from sftChannel.get()
        bos.close(); //the FileOutputStream
        

        因此,您可以理解我递归处理这些操作意味着:

        1. 列出当前目录内容;
        2. 检查第一个条目
          • 如果是目录,请进入内部,然后执行 1。
          • 它是一个文件,下载它
        3. 检查第二个条目 等
        4. 多个测试显示完全相同的行为(并且在这些测试期间下载的内容保持完全相同)。这意味着我的内存使用量会以同样的速度增长。

          [更新1]

          我尝试了一个解决方案,让我让JSch写入FileOutputStream本身:

          final BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(fileToSave));
          sftpChannel.get(remoteFilePath, bos, new SftpProgressMonitor() 
          

          SftpProgressMonitor.end()我关闭 - &gt; bos.close()

          完全没有改变。

          我还尝试按递归方式列出所有文件,将它们各自的字节长度添加到private long totalBytesToDownload,我的程序内存保持非常稳定:在整个过程中只占20Mb(在totalBytesToDownload持续增加的帐户上)确认我的下载方法确实有问题。

          如果我关闭我的溪流,为什么GC不会收集它们?

0 个答案:

没有答案