Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-28311] iOS: File uploads high ram usage

GitHub Issuen/a
TypeBug
Priorityn/a
StatusOpen
ResolutionUnresolved
Affected Version/sn/a
Fix Version/sn/a
ComponentsiOS
Labelsfile, httpclient, ram, upload, usage
ReporterDonovan Lewis
AssigneeAbir Mukherjee
Created2020-12-23T15:48:32.000+0000
Updated2021-08-28T19:15:38.000+0000

Description

When doing a file upload using Titanium on iOS the file will be placed into ram when the upload starts and then removed from ram when finished. This works well for a single or small file. But when you have a large file or multiple file uploads happening at once can be an issue as it is very possible to use more than 1 GB of ram with just a few uploads of files that are not that big. When a upload is started with a 35Mb file for example when it is placed into ram it is not 35Mb of ram usage it seems to be 2x or 3x higher. So doing multiple uploads of a file will hit the devices ram hard. This can cause the app to crash or other apps be closed by the OS that should not be closed because you choose to upload a large video or a few files. We need the option to upload from disk not from ram. It seems we can use "NSInputStream" to upload the file from the disk not placing it into ram. More discussed here on how to do this: https://stackoverflow.com/questions/12626748/what-is-the-correct-way-of-sending-large-file-through-http-post-without-loading/12627138#12627138

Comments

  1. Vijay Singh 2021-01-09

    Moved to TIMOB to investigate on this.
  2. Donovan Lewis 2021-02-21

    Here is a sample code, If you use this code with a 100 MB file to upload, one steam will use over 400 MB of ram while the upload is running. If you run multiple steams of the upload it is very easy to exhaust the devices entire amount of ram. Using a smaller file say 10MB and having multiple uploads at once it will use many hundreds or even a gigabyte of ram. This causes apps in the background to close. We need a way to not have the file being uploaded placed into ram.
       var xhr = null;
        
       var win = Ti.UI.createWindow({
         backgroundColor: '#fff',
         fullscreen: false, navBarHidden: true, exitOnClose: true, theme: "Theme.materialTheme", orientationModes: [Titanium.UI.PORTRAIT]
       });
        
       var runTime = Ti.UI.createLabel({
         text: 'Run Time...',
         top: 50,
         left: 10,
         color: '#000'
       });
        
       var uploadSpeed = Ti.UI.createLabel({
         text: '0.00 Mbps',
         top: 90,
         left: 10,
         color: '#000'
       });
        
       var buttonStart = Ti.UI.createButton({ title: "START", width: 100, height: 40, top: '45%', left: '10%' });
       var buttonStop = Ti.UI.createButton({ title: "STOP", width: 100, height: 40, top: '45%', right: '10%' });
        
       var uploadfile = Ti.Filesystem.getFile(Ti.Filesystem.getResourcesDirectory(), "100MB.bin").read();
        
       buttonStart.addEventListener("click", function() {
        
         console.log('Starting Upload');
        
         var startTime = new Date().getTime();
         var totalPercent = 0;
        
         xhr = Titanium.Network.createHTTPClient();
         xhr.onsendstream = function(e){ 
             console.log(e.progress);
        
             totalPercent = (e.progress).toFixed(2);
             var currentTime = new Date().getTime();
             var timeDiff = ((currentTime-startTime)/1000).toFixed(2);
             var totalDownloaded = (102400 * totalPercent);
             var currentKBPS = (((((totalDownloaded * 1024) * 8.192) / timeDiff) / 1024 / 1024)).toFixed(2);
        
             runTime.text = timeDiff;
             uploadSpeed.text = currentKBPS + ' Mbps';
         };
        
         xhr.onload = function(e) {
        
         };
         xhr.open('POST','http://sfo.veeapps.com/upload.php');
         xhr.send({media: uploadfile });
         
       });
        
        
       buttonStop.addEventListener("click", function() {
         xhr.abort();
         xhr = null;
       });
        
       win.add(runTime);
       win.add(uploadSpeed);
       win.add(buttonStart);
       win.add(buttonStop);
       win.open();
       
  3. Donovan Lewis 2021-08-28

    Has anyone else been able to take a look at this?

JSON Source