4

I am trying to process a string that is the result of an API call. Unfortunately the return value is a really long String (nearly 6 million characters, Length: 5468120), so when I am trying to do some work on it (converting the json string into a map) I get the exception:

System.LimitException: Apex heap size too large: 12238804

I was also trying to break the string maybe into 3 parts, but I got also the error message:

List<String> txtLST = txt.split(']');

Regex to complicate

Is there any work around to this? or I just need to try to convince the API provider to reduce the size of the string?

This API will be call in a cron job, with the purpose of updating an object in salesforce, so there will be no interaction between the user and the API response (unless the interaction in the salesforce tab)

EDIT:

webservice static void bringInfo(){
    String reqBody = 'XXXXXX';
    String apiResponse;
    String environment;
    String reqEndpoint = 'YYYYYYY';

    Http http = new Http();
    HttpRequest req = new HttpRequest();
    HttpResponse res = new HttpResponse();

    req.setTimeout(120000);
    req.setEndpoint(reqEndpoint);
    req.setHeader('Content-Type', 'application/json');
    req.setBody(reqBody); 
    req.setMethod('POST');

    //method 2: Apex heap size too large: 8314825
    Object untypedJson;
    try {
        untypedJson = JSON.deserializeUntyped(new Http().send(req).getBody());
    } catch(CalloutException e) {
        System.debug(e);
    }

    //IF i change above lines to method 1:
    //method 2: Apex heap size too large: 11106456
    Object untypedJson;
    {
        Http h = new Http();
        HttpResponse r = h.send(req);
        // You can check r's status code, etc, first, but the last thing
        // you should do before closing the scope is...
        untypedJson = JSON.deserializeUntyped(r.getBody());
    }        
}
3
  • What are you trying to do with the string? If you are trying to split a CSV this will help you past the regex too complex: gist.github.com/jkentjnr/8f4217f9027c2427227f although with a file that large you may have to store it as a document/file and move to batch processing – Eric May 1 '16 at 3:55
  • did you manage to find a solution? – Javier García Manzano Jan 8 '18 at 15:38
  • @JavierGarcíaManzano yes and no, the solutions provided by sfdcfox didnt work for me, but I change the method to @ future and that increased the heapsize to double, I coincidentally found this doc still on pilot but seems really interesting: developer.salesforce.com/docs/atlas.en-us.apexcode.meta/… – manza Jan 8 '18 at 22:53
4

The heap limit is only checked every few milliseconds, so all you need to do is release the HttpResponse before the next heap check. The easiest way to do this is to discard the HttpResponse after the JSON conversion. Here's one possible way:

Object untypedJson;
{
    Http h = new Http();
    HttpResponse r = h.send(req);
    // You can check r's status code, etc, first, but the last thing
    // you should do before closing the scope is...
    untypedJson = JSON.deserializeUntyped(r.getBody());
}
// r is now discarded, freeing the 5.8 MB of heap that would have been used.

Alternatively, if you don't care about the status code, etc, you can always just use a try-catch block:

Object untypedJson;
try {
    untypedJson = JSON.deserializeUntyped(new Http().send(req).getBody());
} catch(CalloutException e) {

}

The heap won't be checked during the the entire line of code because there's no user-defined function calls in the code.

3
  • 1
    Learn something new every day. Did not know regex to complicated was related to heap..... – Eric Apr 27 '16 at 5:31
  • @Eric Actually, "regex too complicated" happens when you try to use split on a string more than 1,000,000 characters long (or any other regex, like Matcher). The main point of my answer was to discard intermediate storage as soon as possible so the runtime wouldn't kill your process for using too much memory. I've gotten away with temporarily using ~25MB of heap in a limit of 12MB by using that trick. You might say, it's the garbage collector that enforces the heap limit. – sfdcfox Apr 27 '16 at 15:11
  • Hi @sfdcfox , unfortunately I keep getting the error: Line: -1, Column: -1 System.LimitException: Apex heap size too large: 8314825 (with the second method, with the first the size is 11106456), so i am not sure if this is what you meant or if I am doing something different? – manza May 1 '16 at 3:37

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.