1. 程式人生 > >建立ExecutorService並行處理任務,導致記憶體不足

建立ExecutorService並行處理任務,導致記憶體不足

利用ExecutorService建立的執行緒池並行地處理任務,可以節省總的等待時間(總等待時間等於耗時最多的那個任務的耗時)。不過執行緒池不會被自動地釋放。所以要麼建立一次執行緒池之後重複地使用,要麼每次使用完之後顯式地釋放掉。不然的話最終會導致記憶體被用光。 問題現象: 使用Executors建立執行緒池批量並行處理任務(比如請求外部介面),過一段時間之後,jvm報OutOfMemory錯誤,程序死掉。 觀察,通過jstack觀察執行緒數,某些型別的執行緒一直在增長: jstack <pid> | grep "waiting on condition" | wc -l jstack <pid> | grep "waiting on condition"| grep pool |wc -l 問題程式碼(batchProcess不斷被呼叫):
private void batchProcess(List<Integer> idList) throws Exception {
   ExecutorService executorService = Executors.newFixedThreadPool(idList.size());
   List<AreaThread> taskList = new ArrayList<>();
   for(Integer id : idList){
      taskList.add(new AreaThread(id));
   }

   List<Future<Integer>> futureList = executorService.invokeAll(taskList);

   List<Integer> resultList = new ArrayList<>();
   for(Future<Integer> future : futureList){
      Integer result = future.get();
      logger.debug("result={}", result);
      resultList.add(result);
   }
}

原因:executorService 沒有被顯式地關閉,執行緒池建立之後一直在等待新的任務,越積越多。 改正後的程式碼:
private void batchProcess(List<Integer> idList) throws Exception {
   ExecutorService executorService = Executors.newFixedThreadPool(idList.size());
   List<AreaThread> taskList = new ArrayList<>();
   for(Integer id : idList){
      taskList.add(new AreaThread(id));
   }

   List<Future<Integer>> futureList = executorService.invokeAll(taskList);

   List<Integer> resultList = new ArrayList<>();
   for(Future<Integer> future : futureList){
      Integer result = future.get();
      logger.debug("result={}", result);
      resultList.add(result);
   }

   executorService.shutdown(); //如果不shutdown,執行緒池一直不會釋放
}

或者:建立一個公用的executorService,讓它一直存在,所有的批量任務都使用它。

相關推薦

建立ExecutorService並行處理任務導致記憶體不足

利用ExecutorService建立的執行緒池並行地處理任務,可以節省總的等待時間(總等待時間等於耗時最多的那個任務的耗時)。不過執行緒池不會被自動地釋放。所以要麼建立一次執行緒池之後重複地使用,要麼每次使用完之後顯式地釋放掉。不然的話最終會導致記憶體被用光。 問題現象

並發實戰:多線程處理任務結束後執行後續操作

batch add 批次 for return countdown executors 操作 current 場景: 分批從大列表 blist 讀取數據,執行驗證過濾,符合條件的加入到列表中。然後執行批量入庫操作。 思路: 多任務從 blist 取數據執行,采用Excuet

C# 載入和傳遞圖片導致記憶體溢位的問題

      由C#向C++裡面傳遞影象的過程中,多載入幾次影象後,記憶體會暴漲,主要有兩個原因: 一、pictureBox的清理不能用pictureBox.Image=null清除,而應該使用,pictureBox1.Image.Dispose()。 二、B

介面資料量太大導致記憶體溢位解決辦法

通常我們使用介面呼叫資料總是返回一段我們需要的資訊,或者是json 格式資訊,通過接收將資料儲存到程式當中,再對接收到的資料進行轉換成對應的模型格式 。目前遇到的問題是接收的資料量過於巨大,導致完整接收將導致記憶體溢位,無法進行接下去的工作 。 解決辦法: 我們將資料儲存到本地檔案 ,再通過

安卓Handler當做內部類導致記憶體洩露的問題

this handler should be static or leaks might occur   How to Leak a Context: Handlers & Inner Classes Context是怎麼洩露的:Handlers & In

工作流activiti之啟動例項物件查詢處理任務完成要處理任務

/** * 啟動流程例項物件 */ @Test public void testStartProcess() { ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); RuntimeSe

Microsoft TPL Dataflow 並行處理列舉輸出等

TPL DataFlow是一個並行處理資料流的類。使用它可以做為目標輸出流或寫入流。 下面這個示例包括並行處理列舉,並行輸出到控制檯。 using System; using System.Collections.Generic; using System.Linq; u

Android-Fragment 切換造成記憶體溢位導致記憶體增長

    當在Activity裡面有多個fragment的時候,來回切換fragment,會造成記憶體使用一直在增加。    由於fragment在呼叫remove之後,裡面的view的引用導致記憶體回收不了,造成記憶體洩露,所以不斷的new Fragment切換之後,記憶體使

PHP多程序處理並行處理任務例項

本文目的 本文通過例子講解linux環境下,使用php進行併發任務處理,以及如何通過pipe用於程序間的資料同步。寫得比較簡單,作為備忘錄。 PHP多程序 通過pcntl_XXX系列函式使用多程序功能。注意:pcntl_XXX只能執行在php CLI(命令列)環境下

Rxjava2定時器週期執行任務避免記憶體洩漏

private CompositeDisposable mCompositeDisposable = new CompositeDisposable(); private void test() { mCompositeDi

Android6.0以上應用在長時間在後臺因為記憶體不足導致系統回收記憶體當再次啟動應用出現Fragment重疊或者空白、異常解決方案(提供模擬記憶體不足導致系統回收記憶體的方案)。

  Android6.0以上應用在長時間在後臺,因為記憶體不足導致系統回收記憶體,當再次啟動應用出現Fragment重疊或者空白解決方案。首先提供一個方法模擬記憶體不足導致系統回收記憶體的方案:開啟Android Studio -->Tools-->Android

mysql innodb引擎 長時間使用後資料檔案遠大於實際資料量導致空間不足

近期我碰到了一個令人頭疼的事情。就是我的mysql伺服器使用了很久之後,發現/data  目錄的空間佔滿了我係統的整個空間,馬上就要滿了。下面是我的分析。 在網上查看了這2個方法,但是執行後發現沒有解決。系統空間沒有變小。 1.optimize table table.n

Kafka啟動顯示記憶體不足修改記憶體

I am using DigiOcean instance with 512 megs of ram, I get the below error with kafka. I am not a java proficient dev. How do I adjust kafka to utilize th

python分塊讀取大資料避免記憶體不足

def read_data(file_name): ''' file_name:檔案地址 ''' inputfile = open(file_name, 'rb') #可開啟含有中文的地址 data = pd.read_csv(in

Kafka啟動顯示記憶體不足

常見命令: -Xmx    Java Heap最大值,預設值為實體記憶體的1/4,最佳設值應該視實體記憶體大小及計算機內其他記憶體開銷而定; -Xms    java Heap初始值,Server端JVM最好將-Xms和-Xmx設為相同值,開發測試機JVM可以保留預

掛載swap解決記憶體不足的編譯錯誤

編譯程式時,如果出現類似virtual memory exhausted: Cannot allocate memory的錯誤時,可以用下面的方法解決。 建立swap掛載點 # mkdir /opt/images/ # rm -rf /opt/images/swap 設定

MS SQL執行大指令碼檔案時提示“記憶體不足”的解決辦法

問題描述: 當客戶伺服器不允許直接備份時,往往通過匯出資料庫指令碼的方式來部署-還原資料庫, 解決辦法: 用微軟自帶的sqlcmd工具,可以匯入執行。以SQL Server 2008R版本為例: 第一步:Win+R 鍵入:cmd 命令,開啟命令列工具; 第二步:鍵入:cd

Java7 Fork-Join 框架:任務切分並行處理

package forkJoin; import java.util.concurrent.RecursiveTask; public class SumTask extends RecursiveTask<Integer> { private static final int THR

移動查勘通賠版本系統上線-對接理賠失敗導致案件無法正常下發及處理

工作事故升級開始時間:2017-5-4晚19:00升級結束時間:2017-5-4晚22:002017-5-5-周五:出現問題:大部分分公司反饋無法接受通賠案件,一小部分分公司反饋能收到案件,但是無查勘信息。實際原因:在做升級操作之前,考慮不周導致,只考慮了分公司是否需要做操作,除試點分公司需要做部分操作之外,

虛擬機移動磁盤中途服務器斷電導致磁盤鎖定的處理辦法

ovirt可以通過修改數據庫,步驟如下1、OVIRT進入數據庫[root@vmhost2 ~]# su postgres 進入數據庫bash-4.2$ psqlcould not change directory to "/root"psql (9.2.23)Type "help" for help.2、po