How can i avoid XHR POST Memory leak? I go through lots of web pages regarding XHR memory leak but there is no good solutions. My problem is almost similar to this That blog explains the problem but no solutions.
My Problem: I have a web app which Continuously send date to server (2Mb to 80Mb) and it will make 10 to 300 requests. It is POST request. for GET request no big problem like this.
How can i solve this? Circular reference, Scope , closer etc i try but no success. i try to use delete keyword for readystate change, delete previous xhr object , try to reuse xhr , xhr reference to null , changing coding patters etc
This is the sample code. this is the functionality i need
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 acplish this without Memory leaks?
How can i avoid XHR POST Memory leak? I go through lots of web pages regarding XHR memory leak but there is no good solutions. My problem is almost similar to this That blog explains the problem but no solutions.
My Problem: I have a web app which Continuously send date to server (2Mb to 80Mb) and it will make 10 to 300 requests. It is POST request. for GET request no big problem like this.
How can i solve this? Circular reference, Scope , closer etc i try but no success. i try to use delete keyword for readystate change, delete previous xhr object , try to reuse xhr , xhr reference to null , changing coding patters etc
This is the sample code. this is the functionality i need
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 acplish this without Memory leaks?
Share edited Sep 2, 2016 at 6:04 Jaromanda X 1 asked Sep 2, 2016 at 5:51 VishnuVishnu 7511 gold badge7 silver badges24 bronze badges 18- I don't see what you are trying to achieve with that odd looking sendRequest function - never seen anybody do that - what do you think its purpose is? - or the array, with a single element ... it's all bizarre code, that looks like it's designed to cause issues – Jaromanda X Commented Sep 2, 2016 at 5:59
- purpose is to measure the upload speed of the connection – Vishnu Commented Sep 2, 2016 at 6:01
- well, it doesn't do anything like that - not sure if it would cause an error or keep sending the data repeatedly ... oh, I see, it's supposed to send then when done, send again, infinitely – Jaromanda X Commented Sep 2, 2016 at 6:02
- I also try if(Self.xhr.readyState == 4 && Self.xhr.status == 200){} No change! – Vishnu Commented Sep 2, 2016 at 6:06
- So this function repeatedly sends a large POST request once the previous request has finished ... and you're wondering where the memory leak is ... – Jaromanda X Commented Sep 2, 2016 at 6:07
4 Answers
Reset to default 3continuously + size of request + amount of requests. I think you should not be using XHR for that situation. maybe WebRTC, Long Polling or Web Sockets. Even if you find a workaround to perform it in that way, this will not scale.
Clean up your code - this should do the same thing without the bizarre and pointless use of Self, and the array ... it also re-initializes xhr
I've changed to add a listener to the upload load event - a quick test here seems to not leak (seems to)
// snip
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 ();
for every request you send, you add a new onload handler.
Self.xhr[0].onload = function (test) {
sendRequest ();
};
The old handler will not be deleted at this point and stays in memory. The garbage collector will not be able to free the memory.
In your case you only ever need one eventlistener, so i remend moving the attachment of the listener out of the sendRequest function like so, and the memory leak should be gone.
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 ();
EDIT: Version 2
i have tried another version which produces even better results. memory never surpasses 2.6G on my setup. Its a derivation of Jaromandas work.
It's basicly his version with an 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 ();
Try a newer modern method, using fetch...?
let url = '/upload.php'
let myInit = {
method: 'post',
cache: 'no-store',
body: new ArrayBuffer(2000000)
}
function sendRequest() {
return fetch(url, myInit)
.then(res => res.blob())
.then(sendRequest)
}
sendRequest()