Skip to main content

I'm getting Apex head size limit while manipulating string.

Here is my example :

 

ContentVersion cv = [SELECT Id, VersionData, PathOnClient FROM ContentVersion WHERE Id = '0685r000001z4GvAAI']; // 0685r000001z4MUAAY

Blob versionData = cv.VersionData; // 2Mo (2_358_962)

String message = EncodingUtil.base64Encode(versionData);

System.debug('0. '+Limits.getHeapSize());

for (Integer i = 0; i < 100; i++) {

message = message.substring(0, message.length() - 1);

System.debug((i + 1) + '. ' + Limits.getHeapSize());

}

And here is the output :

18:56:15.28 (28532912)|EXECUTION_STARTED

18:56:15.28 (28540661)|CODE_UNIT_STARTED|[EXTERNAL]|execute_anonymous_apex

18:56:15.28 (30052994)|USER_DEBUG|[2]|DEBUG|1. 1065

18:56:15.28 (156834306)|USER_DEBUG|[31]|DEBUG|versionData.size() : 2358962

18:56:15.28 (202193484)|USER_DEBUG|[33]|DEBUG|0. 3146520

18:56:15.28 (203894050)|USER_DEBUG|[36]|DEBUG|1. 3146531

18:56:15.28 (205469272)|USER_DEBUG|[36]|DEBUG|2. 3146530

...

18:56:15.28 (215428836)|USER_DEBUG|[36]|DEBUG|9. 3146523

18:56:15.28 (217021878)|USER_DEBUG|[36]|DEBUG|10. 3146523

18:56:15.28 (218687727)|USER_DEBUG|[36]|DEBUG|11. 3146522

...

18:56:15.28 (223537621)|USER_DEBUG|[36]|DEBUG|14. 3146519

18:56:15.28 (226547176)|EXCEPTION_THROWN|[EXTERNAL]|System.LimitException: Apex heap size too large: 6291784

18:56:15.28 (226831485)|FATAL_ERROR|System.LimitException: Apex heap size too large: 6291784

How it is possible ?

Do you have any idea about that ?

Thank you

4 risposte
  1. 14 apr 2023, 03:38

    @Cheick Sissoko in Apex, strings are immutable, which means that every time you modify a string, a new copy of the string is created in memory. In your example, you are creating a new copy of the string 100 times in a loop, which causes the heap size to increase rapidly.

    To avoid this issue, you can use a StringBuilder object instead of a string. The StringBuilder object is mutable, which means that you can modify the contents of the object without creating new copies in memory.

    Here is an example of how you can use a StringBuilder object to modify the base64-encoded string:

    ContentVersion cv = [SELECT Id, VersionData, PathOnClient FROM ContentVersion WHERE Id = '0685r000001z4GvAAI'];

    Blob versionData = cv.VersionData;

    String message = EncodingUtil.base64Encode(versionData);

    System.debug('0. '+Limits.getHeapSize());

    StringBuilder sb = new StringBuilder(message);

    for (Integer i = 0; i < 100; i++) {

    sb.deleteCharAt(sb.length() - 1);

    System.debug((i + 1) + '. ' + Limits.getHeapSize());

    }

    message = sb.toString();

    Using a StringBuilder object in this way should help you avoid hitting the heap size limit.

0/9000