Loading
メール配信ドメイン検証状況の確認方法のご案内続きを読む
ただいま大変多くのお問い合わせをいただいており、ご連絡までにお時間を頂戴しております続きを読む

エラー「Apex heap size too large(Apex ヒープサイズが大きすぎます)」

公開日: May 30, 2026
説明

※この記事は英語版を翻訳しており、一部に機械翻訳を含むため内容は後日更新される可能性があります。最新の内容は英語版を参照してください。表示言語は画面右下の言語名から切り替えられます。

Salesforce(セールスフォース)で「Apexヒープサイズが大きすぎます」エラーは、メモリ使用量が制限を超えた場合に発生します。同期トランザクション(Transaction)では6MB、非同期トランザクションでは12MBの制限があります。現在の値は Apex 開発者ガイド に記載されています。コードの最適化とベストプラクティスの遵守が必要です。具体的には、クラスレベルの変数を避け、SOQL Forループを利用し、不要な変数を早期に解放することが推奨されます。

ヒープ(heap)制限を超える Apex (エイペックス)コードの例を次に示します。 
 

@isTest
private class heapCheckIssue{
    static testMethod void myTest(){
        String tStr = 'aaaaa bbbbb ccccc ddddd eeeeee fffff ggggg 11111 22222 33333 44444';
        List<String> baseList = tStr.split(' ');
        List<String> bigList = baseList;
        Map<integer, List<String>> SampleMap = new Map<integer, List<String>>();
        SampleMap.put(1, bigList);
        
        for (integer i=0; i<50; i++) {
            List<String> tempList = new List<String>();
            tempList = SampleMap.get(1);
            bigList.addAll(tempList);
        }
        system.debug('FINAL LIST SIZE IS '+bigList.size());
    }
}

この例は、コレクションの誤った使用を示しています。
List baseList、SampleMap の値、および List tempList が同じメモリアドレスを参照しています。その結果、ヒープサイズはループの反復ごとに 2 倍になります。

 

 

解決策

次の例は、ヒープサイズを超えない同様のアルゴリズムを示しています。 
 

@isTest

private class heapCheckSuccess{
  static testMethod void myTest(){
    String tStr = 'aaaaa bbbbb ccccc ddddd eeeeee fffff ggggg 11111 22222 33333 44444';
    List<String> baseList = tStr.split(' ');
    Map<integer, List<String>> Sample = new Map<integer, List<String>>();
  List<String> bigList = baseList;     Sample.put(1, bigList);
  List<string> myList = new list<string>(); //Declare a new list     for (integer i=0; i<50; i++) {
      List<String> tempList = new List<String>();
      tempList = Sample.get(1);
      system.debug('templist: ' + tempList.size());
    system.debug(' bigList: ' + bigList.size());       myList.addall(tempList); //original code is  bigList.addall(tempList);
    }     system.debug('FINAL LIST SIZE OF bigList IS '+ bigList.size());
    system.debug('myList IS '+mylist.size());
  }
}

上記の例では、bigList 変数を使用する代わりに、新しい List を使用して各反復で tempList の値を格納してからリストを追加しているため、ヒープサイズが大きくなりすぎることはありません。


Apex ヒープサイズ内で実行するためのベストプラクティス

  • 大量のデータを格納するクラスレベルの変数は使用しない。
  • SOQL For ループを利用して、大規模なクエリからのデータを反復処理する。
  • 変数が不要になったらすぐに範囲外になるメソッドとループを作成する。


以下のサンプルでは、50000 個の項目を処理できますが、最大のヒープには検索語、クエリ、200 件の取引先のリスト、および結果のリストが含まれます。これは、処理されているすべての範囲では比較的少ない量です。
 

public with sharing class myClass{

private String myString;

    public myClass(String searchString) {
        myString = searchString;
    }

    private string getQueryString() {
        return 'SELECT Id, Name FROM Account LIMIT 50000';
    }

    public List<Account> getSearchResults() {
        List<Account> searchResults = new List<Account>();
        for(List<Account> accts : Database.Query(getQueryString())) {
            // Each loop processes 200 items
            for(Account a : accts) {
                if (a.Name != null && a.Name.contains(myString)) {
                    searchResults.add(a);
                }
            }
        }
        return searchResults;
    }
}

 

このトピックについての詳細は、SOQL For ループに関するドキュメントを確認してください。

ナレッジ記事番号

000384468

 
読み込み中
Salesforce Help | Article