2

I have two components,

  1. Aura (Parent) --- Showing fields of cases and have create case button
  2. LWC (Child component) --- Using input tag, I am accepting csv and excel of maximum size 3.5 mb. After reading a file using sheet.js in LWC, I am showing a table as well as firing an event to send whole JSON structure of excel sheet to the parent aura component.

Scenario: I am uploading a file (CSV or Excel allowed) from MAC laptop that have 10,000 rows. File size shown on Mac is: 369 KB. Now as I click on save button to create a case, I am sending the JSON structure of excel I received from LWC component and saving it as txt file attached to case. Also, I am not using CHUNK to upload put that json into text file.

But I saw, the file size shown by salesforce for that 10,000 records json txt file is 2.6 MB and the heap size I found at the end of the transaction is 5.2 MB (Close to 6MB). Without uploading a file, maximum heap size is around 1MB.

How can the size of the txt file is increased so high? Also, It there any way I can reduce heap size error.

If anyone wants me to have code, child(LWC) + Parent (Aura) component, please let me know.

Note: I just now pasted a json to character count online for the json, total count of characters: 2689192. Now if I consider one character = 1 byte in salesforce, then on converting 2689192 to MB result 2.6 MB which salesforce is showing size of the file. Am I right that 1 character = 1 byte ?

If yes, then how I can reduce heap size OR is there is any way I can use some javascript remoting in aura js to upload a file separately as javascript is much faster than apex

6
  • I just now pasted a json to character count online for the json, total count of characters: 2689192. Now if I consider one character = 1 byte in salesforce, then on converting 2689192 to MB result 2.6 MB which salesforce is showing size of the file. Am I right that 1 character = 1 byte ?
    – Sukruti
    Aug 22 at 14:26
  • If yes, then how I can reduce heap size
    – Sukruti
    Aug 22 at 14:26
  • 1
    Note that comments are for clarifications. You should generally edit your question to include additional information.
    – sfdcfox
    Aug 22 at 15:34
  • Sure, will do it right now.
    – Sukruti
    Aug 22 at 15:39
  • Why do you need it to be a txt? Can you just add create a ContentDocument? You can use the lightning-file component
    – mnunezdm
    Aug 22 at 15:58

1 Answer 1

3

Every object you can use will take at least eight bytes of memory, four for the data type, and four more for the memory address in the heap. References do not use additional bytes of memory. So, if you start with a JSON string, then use JSON.deserializeUntyped, you'll have the following memory usage:

Type Quantity Size
List[10000] 1 40,008 bytes
Map 10,000 40,000 bytes
String Variable 1 byte per character + 4 bytes per unique string

Like Java, Apex using string pools, so duplicated strings return the same reference and do not count the string length again.

So, a file of 10k rows with 5 fields uses 80,028 bytes of heap, minimum, with duplicate strings counting only once. They are only duplicate if they match the same characters in a case-sensitive manner and of the same length. Substrings of a string are unique strings.

To keep heap space down, process the records in chunks and drop memory as fast soon as you no longer need it.

@AuraEnabled public static void doSomething(String jsonData) {
  List<Object> data = (List<object>)JSON.deserializeUntyped(jsonData);
  jsonData = null; // Immediately discard the JSON since you don't need it
  sObject[] records = new sObject[0];
  while(data.size() != 0) {
    records.add(parseRow(data.remove(0))); // remove row and process
    if(records.size() == 1000) {
      update records;
      records.clear(); // break into chunks of 1000 items
    {
  }
  update records;
}

Using an aggressive algorithm like this will allow you to process the entire JSON, as the heap usage will remain initially stable and actually decrease towards zero (though not completely) as you complete the processing. Of course, this ignore complications like DML limits, CPU limits, etc, but is an effective strategy against heap size.

5
  • Really informative answer, thanks sfdcfox. Just one question, do you feel doing XMLHttpRequest from aura to upload a file from javascript can be done. Or using ajax toolkit in visual force page to create content version directly from javascript can be done?
    – Sukruti
    Aug 22 at 16:55
  • @Rabb The APIs are mostly unavailable in Lightning, as a security feature, but you should be able to use lightning/uiRecordApi createRecord, or in Visualforce, apex:remoteObjects should be able to handle even larger files. You will have to base64 encode them (btoa in your browser).
    – sfdcfox
    Aug 22 at 17:26
  • got it. Will try them too. Also, I just came to your answer in one of the post from stack exchange, "salesforce.stackexchange.com/questions/387604/…".. Just now i tried copying same code and doing upload, I got status as success but cant see the file created.
    – Sukruti
    Aug 22 at 17:34
  • Worked with both: lightning/uiRecordApi createRecord, or in Visualforce, apex:remoteObjects. Thanks Sfdcfox.
    – Sukruti
    Aug 22 at 18:25
  • Hey sfdcfox, apex:remoteObjects doesn't support the content version version data field. I tried passing using btoa and without btoa as well but it does not work. Here is an error " Version Data: value not of required type:"
    – Sukruti
    Aug 23 at 9:41

You must log in to answer this question.

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