2013-06-29 40 views
1

我每5秒創建一個新線程並使用Threadpool exector.我確保線程正在關閉。但我正在逐漸異常:java.lang.OutOfMemoryError,無法創建新的本地線程

Exception in thread "Timer-0" java.lang.OutOfMemoryError: unable to create new native thread.

是它發生,因爲我創造了許多線程,而不是關閉它們?或者經常創造新的?

有人可以告訴我如果我在代碼中做任何錯誤?

public class API{ 
    private MongoStoreExecutor executor = new MongoStoreExecutor(10,50); 
    private class MongoStoreExecutor extends ThreadPoolExecutor { 
     public MongoStoreExecutor(int queueSize, int maxThreadPoolSize) { 
      super(10, maxThreadPoolSize, 30, TimeUnit.SECONDS, 
       new ArrayBlockingQueue<Runnable>(queueSize), 
       new ThreadPoolExecutor.CallerRunsPolicy()); 
     } 
    } 

    public TimerTask alertingPoolsData() throws Exception, UnknownHostException { 
     TimeerTask task = new TimerTask(){ 
      public void run(){ 
       Pools = alertingPools.values().toArray(); 
       List<Future<?>> tasks = new ArrayList<Future<?>>(Pools.length); 
       for (Object pool : Pools) { 
        tasks.add(executor.submit(new DataAccumulation(timeStartSecData, 
         timeEndSec,pool, jsonArrayResult,dataResult))); 
       } 
       for(Future<?> f: tasks) { 
        f.get(2 * 1000L, TimeUnit.MILLISECONDS); 
       } 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     long interval = 5 * 1000L; 
     tm.scheduleAtFixedRate(task,(interval - 
      (System.currentTimeMillis() % interval)), interval); 
     return task; 
    } 
} 
+0

有人可以讓我知道是什麼造成這個問題? – user2325703

+0

爲什麼要將'ThreadPoolExecutor'繼承爲只有一個構造函數調用?這是不好的做法,可能會導致錯誤的編程錯誤。 –

+3

你有沒有檢查過有多少個正在運行的線程(可能使用'Thread.activeCount'?還有:*爲什麼*你會在5秒內啓動新線程?難道只能重新使用同一個池嗎? –

回答

0

我的直覺有,我們不能看到代碼做的事:我懷疑你是在叫alertingPoolsData一遍又一遍的地方。因此,我懷疑你是一次又一次地調度TimerTask。然後,這些組件TimerTasks中的每一個都會重複創建一些未知數量的Future<?>sPools的每個元素),其中每個都將發送到您的MongoStoreExecutor

如果以上所有情況都是如此,則您的線程數曲線上有一個正的一階導數。因此,隨着時間的推移,您將看到線程數的平方增加。你會很快開始擊中upper limits of your native threads

正如評論中所建議的那樣,您可以輕鬆修改當前的實現。我建議組合ScheduledExecutorServiceForkJoinPool

相關問題