Heap size is the amount of memory needed to store the various objects, variables, and state of the Apex transaction in memory. This size is capped at 6MB for synchronous operations and is doubled to 12 MB for asynchronous processes. If the size is increased beyond this capped size then we receive the error “Apex heap size too large”. This post will list out ways to handle heap size for apex code optimization.
To discuss this topic, let us see when we are getting heap size issues so that we can discuss a solution for the issue. As this issue is related to memory utilization while the transaction is in progress, this can be thrown when
- we are calling external API synchronously
- we are working on the file and using its content to write in a local variable for manipulation
- we have a lot of data stored in a global variable
- we are using loops and child loops to get details
Apart from this, there can be other reasons also which are dependent on how we have written our apex code. Here is a sample code that will throw a Heap Size exception when order records will exceed 20000.
Although the code has only SOQL and very simple list usage. A heap size error can be thrown as we are returning complete data from Order object and it is returning a lot of fields. Variable orders is storing complete data so when any calculation or processing will be done on this variable it can throw a heap size exception.
Solution for all above mentioned issues is proper coding which follows best practices. We should write code that will use lesser memory in a transaction. Here are a few best practices that can reduce Heap Size exception
1. Fetch only required records
In the above example, we are returning the complete order list using SOQL which might not be required. Use some filter criteria so that only required records will be fetched. if we have fewer records then it will take lesser memory.
We can use customerid as a filter criteria which will filter records and will reduce heap size. Check out our other post Use Filter in SOQL for the benefits of filtering records.
2. Fetch only required fields
In the above example, we have fetched so many fields but we are not using most of them in the code. All those fetched fields will take time to retrieve from the database and will hold memory as well when saved in any variable like orders in the above example.
We should only fetch the required fields from the database. It will reduce the chances of heap size errors plus the code will work faster as well.
3. Use for loop for SOQL
In the above example, we have performed fetched data from the database and saved complete data in orders variable. This variable is used only in for loop and there is no other usage. We can avoid such type of SOQL and instead of this, we can directly use it in for loop.
Another major benefit of using SOQL in for loop is it will be fetching only 200 records in one go and this way SOQL limit exceptions will not be thrown. So use this concept where ever you can apply it in apex code. I have removed all unused fields in the above example as well, this will also reduce memory size.
4. Avoid system.debug
Avoid the System.Debug in code. It can create issues in production. Checkout our other post for Optimize Code by Disabling Debug Mode
5. Avoid class-level variables and use local variable
Avoid class-level variables as they will be stored in memory until the complete transaction for that class is not finished. It will be better to use a local variable that will automatically release after that block execution.
6. Instead of a big method use smaller methods
As per best practice, we should create smaller methods around 20 lines. We should avoid bigger methods as they will create complexity and dependency in code. A variable created in the method will be alive till the method execution so if we have smaller methods then the variable will be cleaned early just after method execution so our heap size will have more space to hold other objects.
In the case of a bigger method, the variable will be in the heap until the complete method is not executed, it will take some space and might be a reason for the heap size exception. So better will create smaller methods.
7. Free memory when not in use
Where ever we are using objects to store data, try to remove them from memory immediately after use. We should not leave everything for the system to clean. Make a practice to clean it immediately and free some memory from the heap. This will help in storing other data for functionality. In the above example, we have an orders variable that can be cleaned after for loop. Assign null to clean object memory.
8. Use Asynchronous Methods
Sometimes we need to do some heavy operations and it might need to use too much memory, in that case, we can use asynchronous methods so that the heap size will be increased to 12MB and we can complete our apex transaction. We can use Future callouts, queueable methods, or batch jobs based on the requirement. We can use this approach for callout, file handling, etc.