Uploaded image for project: 'HttpComponents HttpAsyncClient'
  1. HttpComponents HttpAsyncClient
  2. HTTPASYNC-77

Client leaks file descriptors if .execute() not called

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Fixed
    • 4.0.1
    • 4.0.2
    • Ubuntu 12.04, possibly others

    Description

      This leaks one anon_inode and two pipes:

      CloseableHttpAsyncClient client = HttpAsyncClients.createDefault();
      client.start();
      client.close();
      

      This does not:

      CloseableHttpAsyncClient client = HttpAsyncClients.createDefault();
      client.start();
      client.execute(new HttpGet("https://issues.apache.org/jira/"), null);
      client.close();
      

      Full sample code (for Linux):

      import org.apache.http.client.methods.HttpGet;
      import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
      import org.apache.http.impl.nio.client.HttpAsyncClients;
      import java.io.BufferedReader;
      import java.io.IOException;
      import java.io.InputStreamReader;
      import java.lang.management.ManagementFactory;
      import java.util.concurrent.ExecutionException;
      
      public class Benchmark {
      
          public static void main(String[] args) throws ExecutionException, InterruptedException, IOException  {
              printFileDescriptorCounts();
              for(int i = 0; i < 20; i++) {
                  CloseableHttpAsyncClient client = HttpAsyncClients.createDefault();
                  client.start();
                  // uncomment the next line to fix the leak
                  // client.execute(new HttpGet("http://stackoverflow.com/questions/23966483"), null);
                  client.close();
                  printFileDescriptorCounts();
              }
          }
      
          // not portable -- Linux only
          private static void printFileDescriptorCounts() throws IOException {
              String processId = ManagementFactory.getRuntimeMXBean().getName().split("@")[0];
              String cmd = String.format("lsof -p %s | grep 'anon_inode\\|pipe' | awk '{ print $NF; }' | sort | uniq -c", processId);
              Process process = Runtime.getRuntime().exec(new String[]{"/bin/sh", "-c", cmd});
              BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
              try {
                  for(String line; (line = br.readLine()) != null; ) {
                      System.out.print(line.replace("\n", "\t"));
                  }
                  System.out.println();
              } finally {
                  br.close();
                  process.destroy();
              }
          }
      
      }
      

      Attachments

        Activity

          People

            Unassigned Unassigned
            draperp Paul Draper
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: