Massive Memory Drain Due to XMLHttp POST Request

Is there a way to prevent XHR POST Memory leak in my web app? I have searched extensively for solutions but have not found any satisfactory answers. My issue is similar to the one described in this blog post that outlines the problem without offering any fixes.

My Dilemma: I am continuously sending large amounts of data (2Mb to 80Mb) to the server through POST requests, ranging from 10 to 300 requests. This problem does not occur with GET requests.

What can I do to resolve this? I have tried addressing circular references, scopes, closures, and more without success. Attempting to use the delete keyword during readystate changes, deleting previous XHR objects, reusing XHR objects, setting XHR references to null, and altering coding patterns all have not yielded positive results.

Below is a sample code illustrating the functionality I require:

 var base_string = "ABCDEFGHIJKLMNOPQUST01234567890!@#$%^&:ABCDEFGHIJKLMNOPQUST01234567890!@#$%^&ABCDEFGHIJKLMNOPQUST01234567890!@#$%^&";
            base_string += base_string;  
            base_string += base_string; 
            base_string += base_string; 
            base_string += base_string;  
            base_string += base_string;  
            base_string += base_string;  
            base_string += base_string;  
            base_string += base_string; 
            base_string += base_string;  
            base_string += base_string;  
            base_string += base_string; 
            base_string += base_string;  
            base_string += base_string;  
            base_string += base_string;  
            base_string += base_string;  
            base_string += base_string;  
            base_string += base_string;  
            this.sampleData = base_string;
            var dataToSend = this.sampleData.substring(0, 2000000);

           this.xhr = [];
           this.xhr[0] = new XMLHttpRequest();
           function sendRequest (){
               var Self = this;
               Self.xhr[0].onload = function (test) {
                   sendRequest ();
               };

               Self.xhr[0].open("POST", "http://localhost/upload.php" + "?n=" + Math.random(), true);
               Self.xhr[0].send(dataToSend);
           }
           sendRequest ();

How can I achieve this functionality without encountering memory leaks?

Answer №1

Consistently monitoring the size and volume of requests can be challenging when using XHR. It may be more suitable to explore alternatives such as WebRTC, Long Polling, or Web Sockets for better scalability. Trying to find a workaround within the limitations of XHR could lead to issues with scaling in the future.

Answer №2

Improve your code by removing the unnecessary use of Self and array, and also re-initializing xhr.

I have made a change to add a listener for the upload load event - a quick test shows that there doesn't appear to be any memory leaks (at least not at first glance).

// snippet
this.sampleData = base_string;
var dataToSend = this.sampleData.substring(0, 2000000);

function sendRequest() {
    var xhr = new XMLHttpRequest();
    xhr.upload.addEventListener('load', function(e) {
         sendRequest();
    });

    xhr.open("POST", "http://localhost/upload.php" + "?n=" + Math.random(), true);
    xhr.send(dataToSend);
}
sendRequest();

Answer №3

With each request sent, a new onload handler is added.

this.xhr[0].onload = function (test) {
    sendRequest ();
};

The previous handler remains in memory and isn't removed, causing a memory leak. The garbage collector can't free up the memory.

If you only need one event listener in your case, it's best to move the listener attachment outside the sendRequest function. By doing this, the memory leak issue should be resolved.

this.xhr = [];
this.xhr[0] = new XMLHttpRequest();
xhr[0].onload = function (test) {
    sendRequest ();
};
function sendRequest (){
    xhr[0].open("POST", "http://localhost/upload.php" + "?n=" +  Math.random(), true);
    xhr[0].send(dataToSend);
}
sendRequest (); 

UPDATE: Version 2

I've tested another version that shows even better results. My setup never exceeds 2.6G of memory usage. It's based on Jaromandas' work with the addition of removeEventHandler and delete.

function sendRequest (){
function run(e){
  xhr.upload.removeEventListener('load',run)
  sendRequest()
}
var xhr = new XMLHttpRequest();
xhr.upload.addEventListener('load', run);
xhr.open("POST", "http://localhost:2345/" + "?n=" +  Math.random(), true);
xhr.send(dataToSend);
delete xhr
}
sendRequest ();

Answer №4

Have you considered a more contemporary approach by using fetch...?

const endpoint = '/uploadData.php'
const options = {
    method: 'post',
    cache: 'no-cache',
    body: new ArrayBuffer(2000000)
}

function sendFetchRequest() {
    return fetch(endpoint, options)
        .then(response => response.blob())
        .then(sendFetchRequest)
}

sendFetchRequest()

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Methods for eliminating curly braces from HTTP response in JavaScript before displaying them on a webpage

When utilizing JavaScript to display an HTTP response on the page, it currently shows the message with curly braces like this: {"Result":"SUCCESS"} Is there a way to render the response message on the page without including the curly braces? This is the ...

Tap on the image to enlarge

I have a question regarding using thumbnails from Bootstrap. I am trying to create functionality where when I click on a thumbnail, the picture with its original sizes appears and then disappears when clicked anywhere else on the page. Below is an exampl ...

Losing values due to custom $validator and getterSetter in AngularJS / UI Bootstrap

My objective is to create a UI Bootstrap datepicker with an input mask feature. The datepicker directive only validates dates selected using the popup window and not dates manually typed in by the user. To address this, I researched how to implement custo ...

Vue3 - Utilizing a method to dynamically alter an input property

Currently, I am in the process of developing a Vue application that incorporates a map feature. The main functionality involves determining whether a given position on the map is over water or land. If the position is over water, I want to iterate through ...

Manipulate a value using JavaScript

While the intention is for the button value to switch between 1 and 0, the echo $_POST["ordina"] consistently returns 1. Despite checking the code multiple times, I am unable to identify the issue. <script> function order() { if (document.ordination ...

The Ubuntu virtual machine hosted on Google Cloud is experiencing difficulties connecting through Node.js using an external IP address

const express = require('express'); const bodyParser = require('body-parser'); const path = require('path'); const app = express(); app.listen(3000, function(){ console.log('Server is now live on port 3000' ...

What could be the reason for the undefined value of my ID retrieved from the next JS router.query upon page refresh?

When using the id obtained from the next router.query to dynamically render elements, it works fine when accessing the room from next/link. However, upon refreshing the page, an error is thrown. https://i.stack.imgur.com/yEjGS.png Below is the code snipp ...

How can Javascript or Jquery determine the specific event assigned to an object?

Is it possible to retrieve the properties of HTML elements using their name or id? For example: document.getElementById('id').value; //Accessing element property in JavaScript $('#id').attr('class'); // Accessing correspond ...

Is there a way to stop Ajax calls initiated with Dajaxice?

Utilizing Dajaxice with my Django-based website has proven to be highly convenient. However, I occasionally encounter the need to cancel Ajax requests and I'm unsure how to do so when they are wrapped with Dajaxice. The documentation for Dajaxice is ...

Troubleshooting issues with submitting forms remotely in Rails

Is there a way to submit a form using ajax/js instead of html? I've tried setting :remote => true, but it still submits as html. <%= form_for(@message), :remote => true, do |f| %> <%= f.label :Note_To_Doctor %> <%= f.text_fi ...

Develop a custom directive that incorporates ng-model and features its own distinct scope

UPDATE - I have generated a Plunker I am in the process of developing a personalized directive to be utilized for all input fields. Each input will have distinct options based on the logged-in user's requirements (mandatory, concealed, etc), so I bel ...

Is it possible to modify the sub/child divs within a draggable parent div and assign them a different class?

Greetings, after being a long-time reader, I have finally decided to post for the first time. In the process of creating a webpage with jQuery drag and drop divs, I am curious about how to change the class of a child div within a draggable div once it is d ...

Integrate JavaScript date into the gulp-rev workflow

I have been encountering an issue while using the gulp-rev plugin to add a revision of my app/html page generated by the Yeomann webapp generator. My workflow involves zipping the app and then adding a revision, but I am having trouble replacing the hash t ...

The Response.Redirect function is failing to execute

I have the following ajax script on my Default.aspx page for login $(document).ready(function () { $('#UserLogin').submit(function (e) { $.post("LoginApp.aspx?formpost=Login", { UserID: $("#UserID").val(), UPass: $("#UPas ...

Is there a way to retrieve bookmarks (TOC) from a PDF document using technologies such as NodeJS, ReactJS, or PHP?

I'm sure most people have noticed that when you open a PDF in the browser or Acrobat PDF reader, a bookmarks tab appears like the one shown here: https://i.stack.imgur.com/obFer.png If the PDF doesn't have any bookmarks, the list will be empty. ...

Go to a different page when a row is selected in a PrimeFaces datatable

My primefaces datatable is displaying a number of records. I want to navigate to another page when a row is selected (for editing the selected entity, for example). The closest example I found was using the p:ajax tag to bind the rowSelect event to a lis ...

Modify meta titles according to specific url #id

My website is built in static HTML and our server does not support PHP or C#. Can JavaScript, jQuery, Ajax, or other technologies achieve the following: If the URL is: Https://example.com/page, the meta title will display as "home page". Https://example ...

What is the best way to display changing session variables in PHP?

Purchase Page: This page allows customers to select business card orders in various foreign languages and customize their options. Whenever a user decides to add an extra card by clicking a button, javaScript dynamically includes new form fields. To ensur ...

Encountered an Error in Express.js: Unable to POST /users

I am currently in the process of learning the MEAN stack by following a tutorial and have encountered an error. Unfortunately, I am having difficulty identifying exactly where I went wrong. While attempting to test routes in Postman by creating a user, I ...

Creating a Command Line Interface (CLI) application in JavaScript for the browser: A guide to simulating blocking I/O

Developing a CLI application becomes quite simple with a blocking I/O API like PrintLn / ReadLn, making the process smooth and efficient. However, the challenge arises when trying to create a terminal application that runs on a browser using JS. In this s ...