6

I have been investigating a potential heap size problem in our production code, and I wanted to recreate some simple elements through the developer console.

To cause a heap size exception, I would select every standard field from account for 50,000 accounts into a list.

System.debug('Heap size before query = ' + Limits.getHeapSize() + ', out of maximum ' + Limits.getLimitHeapSize());
List<Account> accs = [select AccountNumber, AccountSource, AnnualRevenue, BillingCity, BillingCountry, BillingPostalCode, BillingState, BillingStreet,
                             CreatedById, CreatedDate, CurrencyIsoCode, Description, Fax, FirstName, Id, Industry, IsCustomerPortal,
                             IsDeleted, IsPersonAccount, Jigsaw, JigsawCompanyId, LastActivityDate, LastModifiedById, LastModifiedDate, LastName,
                             MasterRecordId, Name, NumberOfEmployees, OwnerId, Ownership, ParentId, PersonBirthdate, PersonContactId, PersonEmail,
                             PersonEmailBouncedDate, PersonEmailBouncedReason, PersonHomePhone, PersonLastCURequestDate, PersonLastCUUpdateDate, PersonLeadSource,
                             PersonMailingCity, PersonMailingCountry, PersonMailingPostalCode, PersonMailingState, PersonMailingStreet, PersonMobilePhone, PersonOtherCity,
                             PersonOtherCountry, PersonOtherPostalCode, PersonOtherState, PersonOtherStreet, PersonTitle, Phone, Rating, RecordTypeId, Salutation, ShippingCity,
                             ShippingCountry, ShippingPostalCode, ShippingState, ShippingStreet, Sic, SicDesc, Site, SystemModstamp, TickerSymbol, Type, Website
                      from account
                      limit 50000];
System.debug('Heap size after query = ' + Limits.getHeapSize() + ', out of maximum ' + Limits.getLimitHeapSize());

This is a full copy sandbox and there are over 50,000 accounts. My expectation was that this would fail with a heap size limit exception.

Instead I get the output:

USER_DEBUG [1]|DEBUG|Heap size before query = 1069, out of maximum 6000000
USER_DEBUG [12]|DEBUG|Heap size after query = 33931975, out of maximum 6000000

Notice the heap size used is 34MB and the limit 6MB but no exception occurs. I have done some more experiments and I can iterate over the list and carry on executing code with the heap size above this level.

Here are the limit usage stats which seem to show 0 heap usage.

Limit stats for execute anonymous

I can't find anywhere that this is expected behaviour for the developer console. My understanding was that the limits apply in all contexts.

Can anyone shed any light on this?

  • It should be same across all contexts with the exception of email services. Well thats my understanding :) Bug? – Francis Jun 16 '16 at 12:57
  • Heap Limits are certainly back for Batch Apex – Scott Pelak Oct 19 '16 at 19:13
5

So I logged a case with support (Case Number 14444735) to find out if this limit has actually been lifted, and here's the response I got:

I have verified in Execute Anonymous and the heap limit is lifted extremely. I am currently investigating as why the execute anonymous from Developer Console does not enforce heap size limit. I will provide you with an update as soon as possible.

And some time later:

I have discussed the issue with my seniors and found that heap size checks are performed according to certain heuristics, meaning they are not performed on evaluating each statement, and as a result it is possible to exceed the limit, but this will be enforced as soon as salesforce checks it.

At that point, I asked for more detail and if there is any plan to change this behavior. He came back with:

As of now we have to [sic] information that R&D team is planning to make any changes to this. But currently the heap limit would cause a crash whenever system checks for it.

You can also get more details regarding this from the below mentioned URL: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_gov_limits.htm

I also asked why Limits.getHeapSize() does not count as checking the limit, and he refused to further explain:

I had a discussion with my seniors regarding the evaluation of heap size as how it works internally but the architecture and internal implementation details cannot be shared.

As explained previously we follow certain heuristics to determine when to compute the heap size (which performs a heap walk), and when to enforce the max heap size, which doesn't occur when invoking Limits.getHeapSize().

  • Thanks for this answer Adrian, this seems like the best explanation we're going to get :-) – Doug B Sep 15 '16 at 9:38
1

This isn't an answer, but a confirmation of what you're experiencing. I was able to similarly use a much larger Heap than the limits of 6 MB or 12 MB in Execute Anonymous.

I wondered if this was just a quirk of Execute Anonymous, so I ran similar Heap-abusing Batch Apex. I was able to go significantly over the 12 MB Asynchronous Heap Size Limit.

I am nearly certain I wasn't able to do this in June 2016. Maybe Salesforce upgraded their hardware and changed their Limits: the CPU Memory was affordable and the 10s CPU Time Limit provided sufficient resource protection. Maybe Salesforce is silently rolling this out to measure how good of an idea this is. Idk.

enter image description here


Update 2016-10-19

I have run into Heap Limits with Batch Apex. I can no longer abuse the Heap as I did above.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.