0

I am running a soql to query 10,000 rows of an object & storing the result in a list. When I check my heap size after the query I see 70MB of heap space getting used & I dont get any exception. We shouldnt be ideally crossing 6MB. Not sure if the SOQL resultset is pointing to some common heap area of my org ? and that area is extensible to more than 6MB? I have been browsing salesforce documentation to get any pointers on this behaviour but couldnt. Can someone explain this behavior?

My class below

public  list<MyCustomObject__c> getCustomObjectData()
{
String fieldsAPIname = DataSelector.getObjectFields('MyCustomObject__c');
List<MyCustomObject__c> customObjList=new List<MyCustomObject__c>(); 
String soql = 'Select  LookupObject__r.Name, '+fieldsAPIname+
              'from MyCustomObject__c order by LookupObject__r.Name';
customObjList=Database.query(soql);
System.debug('Heap Size :----'+Limits.getHeapSize());
return customObjList;
}

       

The moment I clone the data from the above list and put into another list it doesnt allow me to clone more than 6MB of data. So where is the first 70MB heap space coming from & why is it not throwing limits exception.

Thanks Tarique

Log image enter image description here

3
  • Can you post the debug logs as well? Also, Does you custom object have Rich Text Fields? or Fields that can store large amount of data?
    – d_k
    Jul 25, 2018 at 6:34
  • No large data field & no rich text field.
    – TariqueH
    Jul 25, 2018 at 6:43
  • Have attached image of the log above.
    – TariqueH
    Jul 25, 2018 at 6:49

1 Answer 1

2

Apex Code only checks the heap governor limit at certain points (as part of the garbage collection process, presumably). It's entirely possible to temporarily exceed the 6MB/12MB/36MB limits, but only for a brief period of time. This is matter of efficiency, since checking the heap every line of code would be costly. There's also specific situations, like triggers, that can cause additional heap to be used while other heap limits are "set aside." This is noticeable especially in recursive triggers.

You should definitely avoid trying to break the limit, but be aware that there is some ability to exceed some (most) of the governor limits without actually throwing an exception. This is a bit of a moving target, though, and you shouldn't depend on the behavior not being fixed. I've personally exceeded the heap limit, query limit, DML limit, DML rows limit, and CPU limit (possibly others from time to time).

The reason why is that many limits are checked by the Apex runtime only periodically and only in specific places, so until you hit some logic that triggers a governor limit check, you can temporarily exceed them. Presumably, the reason you're going so far above the limit is because you specified so many fields that the query resulted in far too much heap being allocated (you can't get a heap limit exception during a query).

You might also want to read my bit about how heap calculations are a bit fuzzy. Also, while we're on the subject, it doesn't take a lot to get to up to 6MB of memory: 10,000 records requires 180,000 bytes just for the ID field, plus, since you reference a second object, another 180,000 bytes just to get the name. Also, number fields are always Decimal, which is about 40 bytes each, or 400,000 bytes of data for each number field in 10,000 rows of data; if you query just 20 number fields, that's 8,000,000 bytes of data.

4
  • Thanks for quick response. I am surprised that the apex runtime is not checking at all in my case. because I called my class using anonymous apex, lightning controller & it went through with 70MB.
    – TariqueH
    Jul 25, 2018 at 6:51
  • @TariqueH Yes, I haven't puzzled out all the possible scenarios that trigger a heap check, but really short code units can get away with it. "Real" code that you're more likely to write would probably crash.
    – sfdcfox
    Jul 25, 2018 at 6:53
  • thanks a lot for the response. As mentioned above when I started cloning object from my customObjList to a new list, it throws the exception at 76 MB. so seems it didnt allow me more than 6 MB in my custom list. Now how salesforce algorithm was able to catch precisely at 6MB past 70MB unless it wasnt a iterative check? any thoughts?
    – TariqueH
    Jul 25, 2018 at 7:46
  • @TariqueH It's not specified anywhere in the documentation, nor will you find anyone that knows that can tell you. Just know that the limitation typically appears more or less at random from our perspective.
    – sfdcfox
    Jul 25, 2018 at 14:45

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .