5

Hi So I am trying to understand that what is heap and how it is managed in Salesforce.

What I did is created a VF page and a Http callout class, I have stored a large XML on remote server that I am getting back from my Http callout. Also I have made a custom logging method to capture the max heap that is being used through the Http and XML parsing(by passing Limits.getHeapSize()) which works fine.

My confusion is the number do not match, for instance even for a file as big as 5MB my debug shows Maximum heap size: 0 out of 6000000. and my custom logger shows MAX Allowed : 6000000 | Highest Used Heap : 11929380.

Note: I know that I have used a custom login that capture heap using "Limits.getHeapSize()", so if I see a number example "11929380", shouldn't the code fail as I donot have any try catch.

Code details: I am using XmlStreamReader to parse the XML. I am using Transient variable to display the result on screen.

Standard :

enter image description here Custom VF :

enter image description here
Code:

public class HttpCallout{
public static innerResult callout(String endpoint, String type){
    innerResult rs = new innerResult();
    captureMaxResource(Limits.getHeapSize() , Limits.getCpuTime() , 'before http call' , rs);

    Http h = new Http();
    HttpRequest req = new HttpRequest();
    req.setEndpoint(endpoint); // PDF hosted xml
    req.setMethod(type);        
    HttpResponse res = h.send(req);

    captureMaxResource(Limits.getHeapSize() , Limits.getCpuTime() , 'after http call but before parsing' , rs);

    rs.result = parserXML( res.getBody() , rs);

    captureMaxResource(Limits.getHeapSize() , Limits.getCpuTime() , 'after parsing' , rs);
    return rs;
}

public static string parserXML(String xmlStr , innerResult rs){
    //parsing of XML
    captureMaxResource(Limits.getHeapSize() , Limits.getCpuTime() , 'after xml parsing' , rs);
    return null;
}

public static void captureMaxResource(integer heap , integer cpu , string logindex , innerResult rs){
    if(rs.maxHeap != null && rs.maxHeap < heap){
        rs.maxHeap = heap;
        rs.indexmaxHeap = logindex;
    }
    else{
        rs.maxHeap = heap;
    }

    if(rs.maxCPU != null && rs.maxCPU < cpu){
        rs.maxCPU = cpu ;
    }
    else{
        rs.maxCPU = cpu ;
    }
}

public class innerResult{
    public string indexmaxHeap{get;set;}
    public integer maxHeap{get;set;}
    public integer maxCPU{get;set;}
    public string result{get;set;}
}
}
2
  • Can you post psuedo code?
    – javanoob
    Feb 25, 2017 at 13:57
  • @javanoob added pseudo code..
    – user614946
    Feb 25, 2017 at 14:09

2 Answers 2

7

As I discovered when investigating Does execute anonymous from Developer Console not enforce heap size limit?

The support rep responding to my case told me:

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.

Also note that they will not share the specifics of when it will be checked:

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().

4
  • thanks for that internal info.. so is there any way to be sure that for few condition heap will always be there so to avoid it?
    – user614946
    Feb 25, 2017 at 16:56
  • 1
    Nope. I wouldn't rely on any particular behavior not checking for it, but they won't share the internals so we can't really know.
    – Adrian Larson
    Feb 25, 2017 at 17:01
  • As I am not able to find any concrete document on this, I have to park this question and focus on to handle it in code.. but thanks and your answer is the best one for now :)
    – user614946
    Feb 26, 2017 at 12:55
  • so freaking ridiculous... Also, Limits.getHeapSize() seems to be wildly inaccurate.
    – NSjonas
    Sep 4, 2017 at 0:54
0

It is in reference to the amount of memory used by the objects. When you create objects in Apex code, as with Java or any standard programming language, memory is allocated to store the objects. And that memory is allocated from the allocated heap.Think of it is a designated amount of memory you can use up in your Apex request.

for synchronous heap size is 6 MB, for asynchronous it is 12 MB

2
  • thanks for the reply, I get it that it is a runtime memory but my question is that if I log a number way higher then allowed why my code didn't through any error?
    – user614946
    Feb 25, 2017 at 8:13
  • @user614946 The limit isn't imposed in all environments/conditions. Hopefully someone can answer who has a clear understanding of where/when. But bottom line is that the limit is likely to be imposed in production and so you need to address the problem.
    – Keith C
    Feb 25, 2017 at 12:41

You must log in to answer this question.

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