簡體   English   中英

ExecutorService占用過多內存

[英]ExecutorService takes too much memory

情況是這樣的:我必須使用Xfire與服務器交換數據。服務器不能處理太多的並發.50個是極限。所以我計划使用ExecutorService限制並發線程的數量。程序運行20分鍾后,如果並發數為50,則內存使用率接近100%。

這是我的代碼:

公共類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;
}

}

誰能解釋為什么以及如何解決這個問題?

還是有人知道如何限制並發線程的數量?

有兩種可能性:

  • 這是由於線程池中的線程太多而引起的。 每個線程可能具有2Mb堆棧,活動線程很可能在其各自的堆棧上具有對象。

  • 這是由於大量的活動線程加劇了內存泄漏。 (一種可能是由於未正確使用線程局部變量而導致的內存泄漏。)

您需要使用內存分析器進行調查。


如何限制並發線程的數量?

簡單。 減小執行程序的線程池大小。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM