Loading

Error 'Apex heap size too large'

Publiseringsdato: May 30, 2026
Beskrivelse

Salesforce enforces an Apex heap size limit of 6MB for synchronous transactions and 12MB for asynchronous transactions. The "Apex heap size too large" error occurs when too much data is stored in memory during Apex code execution. The current limit values can be found in the Apex Governor Limits documentation.
Review your code carefully and follow best practices to ensure heap usage stays within the limit.

Example of Code That Will Exceed the Heap Size Limit

The following Apex test class demonstrates code that will exceed the heap size limit. The problem is that baseList, the value of SampleMap, and tempList all point to the same memory address. Because of this, bigList.addAll(tempList) doubles the total list size on each of the 50 loop iterations — causing exponential heap growth:

@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());
    }
}

This code causes exponential heap growth because all three variables reference the same underlying memory. After 50 iterations, the list size exceeds the 6MB synchronous heap limit

Løsning

The following examples show how to fix the "Apex heap size too large" error by using separate list variables and SOQL For Loops.

Fix 1 — Use a Separate Variable to Accumulate Results

The corrected version below uses a new myList variable to accumulate results. This keeps heap growth linear rather than exponential:

@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());
  }
}

The key fix is myList.addall(tempList) instead of bigList.addall(tempList). By appending to a new list rather than back to the source list, each iteration adds only the original 11 items rather than doubling the total.

Fix 2 — Use SOQL For Loops for Large Data Sets

The SOQL For Loop pattern below processes up to 50,000 records without loading them all into heap memory at once. Each loop iteration processes a batch of 200 records, keeping peak heap usage small:

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;
    }
}

Best Practices for Staying Within the Apex Heap Limit

  • Do not use class-level variables to store large amounts of data.
  • Use SOQL For Loops to iterate and process data from large queries rather than loading all results into a single collection.
  • Construct methods and loops that allow variables to go out of scope as soon as they are no longer needed.
Knowledge-artikkelnummer

000384468

 
Laster
Salesforce Help | Article