首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Jsch SFTP客户端无法创建新的本机线程

Jsch SFTP客户端无法创建新的本机线程
EN

Stack Overflow用户
提问于 2016-04-20 07:42:47
回答 1查看 1.6K关注 0票数 2

我使用Jsch作为SFTP客户端,从远程SFTP目录读取和写入XML文件。

我使用一个5秒钟的任务来检查新文件是否可用于草稿,循环30或40分钟后,我会得到以下错误

代码语言:javascript
复制
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:]

这是用于创建连接的源代码。

代码语言:javascript
复制
 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 =>允许的本地进程的限制,同样的错误。

我使用了以下命令来执行此操作:

代码语言:javascript
复制
ulimit -u unlimited

我试图创建一个jsch会话池,当jsch会话没有断开连接时,它是不可用的=> "SFTP错误4“。

我的工作被部署在jboss 7上,这是JVM选项:

代码语言:javascript
复制
JAVA_OPTS="-Xms1024m -Xmx1024m -XX:MaxPermSize=256m -Xss1024k"

你对这种治疗有什么建议吗?

谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-04-20 09:38:03

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

如果关闭最后块中的会话和通道(如果有效的话),不幸的是,它将使您试图读取的InputStream失效,从而阻止您正确处理文件。

我将稍微重构代码,这将解决资源耗尽问题,并附带注释:

代码语言:javascript
复制
// 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。容器类将有一个“关闭”方法,该方法将关闭InputStream、通道和会话,然后我将不将通道和会话存储在对象中。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36737032

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档