2016-04-20 43 views
0

我使用Jsch作为SFTP客户端从远程SFTP目录读取和写入XML文件。Jsch SFTP客户端无法创建新的本地线程

我用5秒的工作,以检查是否可用于草稿新文件,之后30或40分钟环我收到以下错误

Caused by: java.lang.OutOfMemoryError: unable to create new native thread 
     at java.lang.Thread.start0(Native Method) [rt.jar:1.7.0_65] 
     at java.lang.Thread.start(Thread.java:714) [rt.jar:1.7.0_65] 
     at com.jcraft.jsch.Session.connect(Session.java:528) [jsch-0.1.53.jar:] 
     at com.jcraft.jsch.Session.connect(Session.java:183) [jsch-0.1.53.jar:] 

这是一个用于创建联接

public InputStream getFile(String path){ 
    Session session = null; 
    Channel channel = null; 
    try { 

     ChannelSftp sftp = openConnexion(session, channel); 
     return sftp.get(path); 

    } catch (SftpException e) { 
     new RuntimeException("Error detected during get file from SFTP specific path : " + e.getMessage(), e); 

    } finally { 
     closeConnexion(session, channel); 
    } 
} 

private ChannelSftp openConnexion(Session session, Channel channel) { 
    try { 
     JSch ssh = new JSch(); 
     session = ssh.getSession("user", "hostname", 22); 
     session.setPassword("password"); 
     session.setConfig("StrictHostKeyChecking", "no"); 
     session.connect(); 
     channel = session.openChannel(SFTP_CHANNEL); 
     channel.connect(); 
     ChannelSftp sftp = (ChannelSftp) channel; 

     return sftp; 

    } catch (JSchException e) { 
     throw new RuntimeException("Error detected during open SFTP connexion : " + e.getMessage(), e); 
    } 
    } 

    private void closeConnexion(Session session, Channel channel) { 
    if (channel != null) { 
     channel.disconnect(); 
    } 
    if (session != null) { 
     session.disconnect(); 
    } 
    } 
源代码

我试图增加JVM线程堆栈的大小,并且还增加了由unix =>相同的错误所允许的本地进程的限制。

我用下面的命令来做到这一点:

ulimit -u unlimited 

我试图创建jsch会话,jsch会话的池时没有断开它,它是不可用的=>“SFTP错误4”

我的工作就是拼命地跑入部署的jboss-AS-7战,这是JVM选项:

JAVA_OPTS="-Xms1024m -Xmx1024m -XX:MaxPermSize=256m -Xss1024k" 

你有这种治疗的建议?

谢谢!

+0

您是否在搜索后关闭连接? –

+0

发布代码。你还要在启动时分配多少JVM内存? – Saheed

+0

源代码已添加。 JVM选项也是。 谢谢你的帮助! –

回答

0

问题是你没有关闭每个循环后的通道和会话,至少会泄漏用于通过SFTP执行下载的线程。

尝试在finally块中关闭会话和通道,如果它工作的话,很不幸会使您尝试读取的InputStream无效;阻止您正确处理文件。

我要稍微重构代码,这应该解决资源枯竭问题,有评论说:

// session and channel are at the object scope 
Session session = null; 
Channel channel = null; 

public InputStream getFile(String path){ 
    // First, close any existing connections. 
    try { 
     closeConnexion(); 
    } catch (SftpException e) { 
     // You can try to handle an issue here; but it's 
     // probably not worth it 
    } 
    try { 
     ChannelSftp sftp = openConnexion(); 
     return sftp.get(path); 
    } catch (SftpException e) { 
     new RuntimeException("Error detected during get file from SFTP specific path : " + e.getMessage(), e); 

    } finally { 
    } 
} 

private ChannelSftp openConnexion() { 
    try { 
     JSch ssh = new JSch(); 
     // use the object's session variable 
     session = ssh.getSession("user", "hostname", 22); 
     session.setPassword("password"); 
     session.setConfig("StrictHostKeyChecking", "no"); 
     session.connect(); 
     // use the object's channel object 
     channel = session.openChannel(SFTP_CHANNEL); 
     channel.connect(); 
     ChannelSftp sftp = (ChannelSftp) channel; 

     return sftp; 

    } catch (JSchException e) { 
     throw new RuntimeException("Error detected during open SFTP connexion : " + e.getMessage(), e); 
    } 
    } 

    private void closeConnexion() { 
    // close object's channel and session 
    if (channel != null) { 
     channel.disconnect(); 
     channel = null; 
    } 
    if (session != null) { 
     session.disconnect(); 
     session = null; 
    } 
    } 

如果我是重新设计这一点,我将返回一个容器类,而不是包含通道,会话和InputStream的InputStream。容器类将有一个'close'方法,它将关闭InputStream,channel和session,然后我不会将通道和会话存储在对象中。

+0

谢谢您的回复!你是对的,显然输入流仍然是开放的...我会测试你的建议。 –

相关问题