当前位置: 首页 > 知识库问答 >
问题:

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

郑博
2023-03-14

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

我使用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会话当它没有断开时,它是不可用的=

我的作业被部署到jboss-as-7上的war中,这是JVM选项:

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

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

非常感谢。

共有1个答案

方高丽
2023-03-14

问题是您没有在每次循环后关闭通道和会话,这将至少泄漏用于通过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、通道和会话,然后我将不在对象中存储通道和会话。

 类似资料:
  • 问题内容: 我看到这样的评论 我见过这个问题的一个地方是,如果您继续创建线程,而不是直接在线程对象上调用run(),而不是调用start()。这将导致线程对象不被取消引用…因此,一段时间后,出现无法创建新本机线程的消息 在Sun Java论坛上 在我的应用程序中,最初我们计划使用线程,但是后来,我们决定不再需要线程,因此我们只调用run()而不是start()。我们是否需要为新的threadCla

  • 在大约1024个线程之后,我们在jboss上得到了“java.lang.OutofMemoryError:无法创建新的本机线程”,因为应用程序消耗了最大的用户进程 你能帮我弄清楚代码哪里不对吗?在service.shutdown()之后,我应该添加tasks.clear()还是tasks.remove(ctgService)? 谢谢。

  • 我试图在(1and1VPS)上运行服务器。就在服务器启动和客户机的几个请求(重新加载网页)之后,我得到了这个错误: 但是当我在计算机上运行时,一切都正常。我使用和Centos5.8新安装制作了自己的虚拟服务器,它也在那里工作。 这个内存不足错误的原因可能是什么?如果你有任何建议,请分享。我不知道该怎么处理这个了。

  • 它的发生是因为我创建了许多线程,而没有关闭它们?还是经常创造新的? 有人能告诉我在代码中是否做错了什么吗?