3

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;}
}
}
  • Can you post psuedo code? – javanoob Feb 25 '17 at 13:57
  • @javanoob added pseudo code.. – user614946 Feb 25 '17 at 14:09
5

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

  • 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 '17 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 '17 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 '17 at 12:55
  • so freaking ridiculous... Also, Limits.getHeapSize() seems to be wildly inaccurate. – NSjonas Sep 4 '17 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

  • 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 '17 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 '17 at 12:41

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.