ExecutorService占用太多内存

时间:2013-07-14 14:34:44

标签: java memory concurrency

情况如下: 我必须使用Xfire与服务器交换数据。服务器无法处理很多并发.50是限制。所以我打算使用ExecutorService来限制并发线程的数量。然后Q& A发现内存的使用是程序运行20分钟后,当它有50个并发时,接近100%。

这是我的代码:

public class CompletionServiceImpl {

private static Logger logger = Logger.getLogger("BackgroundLog");

private int threadNum;

private ExecutorService executor = null;

private CompletionService<Integer> sc = null;

private static CompletionServiceImpl completionServiceImpl = null;

private CompletionServiceImpl(){
    this.threadNum = getThreadNum();
    this.executor = Executors.newFixedThreadPool(threadNum);
    this.sc = new ExecutorCompletionService<Integer>(executor);
}

/***
* get the size of thread pool
***/
private int getThreadNum(){

    int threadNum = 5;
    Properties props = new Properties();
    try {
        props.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("tlWeixinconfig.properties"));
        threadNum = Integer.parseInt(props.getProperty("THREAD_NUM"));
    } catch (IOException e) {
        logger.error(e.getMessage(), e);
    }
    return threadNum;
}


public static CompletionServiceImpl getInstance(){
    if(completionServiceImpl == null){
        synchronized(CompletionServiceImpl.class){
            if(completionServiceImpl == null){
                logger.info("thread pool is initialized.");
                completionServiceImpl = new CompletionServiceImpl();
            }
        }
    }
    return completionServiceImpl;
}

public ExecutorService getExecutor() {
    return executor;
}

public CompletionService<Integer> getSc() {
    return sc;
}

}


公共类MyCallable实现Callable {

private static Logger logger = Logger.getLogger("BackgroundLog");

private String id;

private String usr;

private String type;

private String expireDate;

private String billingURL;

private int timeout;

private int result;

public MyCallable(String id, String usr,String type, String expireDate, String billingURL,int timeout,int result){
    super();
    this.id = id;
    this.usr = usr;
    this.type = type;
    this.expireDate = expireDate;
    this.billingURL = billingURL;
    this.timeout = timeout;
    this.result = result;
}

 private int newinsertdrawcn(int result)throws Throwable {
        try {
            URL url = new URL(billingURL);
            HttpURLConnection httpConnection = (HttpURLConnection)url.openConnection();
            httpConnection.setConnectTimeout(timeout);

            httpConnection.connect();
            Client client = new Client(httpConnection.getInputStream(), null);
            client.setProperty(CommonsHttpMessageSender.HTTP_TIMEOUT, String.valueOf(timeout));
            client.setProperty(CommonsHttpMessageSender.DISABLE_KEEP_ALIVE, "true");
            client.setProperty(CommonsHttpMessageSender.DISABLE_EXPECT_CONTINUE, "true");

            Object[] results = client.invoke("drawcn", new Object[] {id, usr, type, expireDate });
            if (results.length > 0) {
                result = Integer.parseInt(results[0].toString());
            }
        } catch (Throwable t) {
            throw t;
        }
        return result;
    }

@Override
public  Integer call(){
    try{
        result = newinsertdrawcn(result);
    }catch(Throwable t){
        logger.error(t.getMessage(),t);
    }
    return result;
}

}

有人可以解释为什么以及如何解决这个问题吗?

或者是否有人知道如何限制并发线程的数量?

1 个答案:

答案 0 :(得分:1)

有两种可能性:

  • 这是由于线程池中有太多线程引起的。每个线程可能有一个2Mb堆栈,活动线程很可能在各自的堆栈上有对象。

  • 这是由内存泄漏引起的,这些内存泄漏会因许多线程处于活动状态而加剧。 (一种可能是由于未正确使用线程局部变量而导致内存泄漏。)

您需要使用内存分析器进行调查。


  

如何限制并发线程的数量?

简单。减少执行程序的线程池大小。