Memory Leak

Users and developers helping users with generic and technical Pale Moon issues on all operating systems.

Moderator: trava90

Forum rules
This board is for technical/general usage questions and troubleshooting for the Pale Moon browser only.
Technical issues and questions not related to the Pale Moon browser should be posted in other boards!
Please keep off-topic and general discussion out of this board, thank you!
User avatar
RobertE1997
Moongazer
Moongazer
Posts: 8
Joined: 2022-11-29, 22:47

Memory Leak

Unread post by RobertE1997 » 2022-11-29, 23:05

Operating system:Debian 11 XFCE, armhf/armv7l, BeagleBone Black, 5.10.109-ti-r44
Browser version: 31.4.0-1.gtk3.mx21
32-bit or 64-bit browser?:
Problem URL:Self
Browser theme (if not default):
Installed add-ons:
Installed plugins: (about:plugins):



There seems to be a memory leak on the browser with this simple code I added. When I monitor the memory of palemoon using "pidstat -r -C palemoon", the memory just continuously grows, not at a fast rate however.

Code: Select all

<!DOCTYPE html>
<html>
<head>
<script src="test.js"></script>
</head>
<body>
<h1>DEVICE</h1>
<span id="rf_data"></span>
<br>
<span id="php_mem"></span>
</body>
</html>

Code: Select all

"use strict";
var id;



function test(){
	const xhttp = new XMLHttpRequest();
	xhttp.onload = function(){
		document.getElementById('rf_data').textContent=this.responseText;
	}

	xhttp.open("GET", "test_ajax.php");
	xhttp.send();
        clearInterval(id);
        id = setInterval(test, 1000);
}

test();
id = setInterval(test, 1000);

Code: Select all

<?php


echo rand() . rand() . rand() . rand() . rand() . rand() . rand() . rand() . rand() . rand() . rand() . rand() . rand();
?>
Also, why did the old armhf version of palemoon get removed? I understand that there are bugs with the latest version for armhf, but why not keep the latest working version available?

User avatar
Moonchild
Pale Moon guru
Pale Moon guru
Posts: 35479
Joined: 2011-08-28, 17:27
Location: Motala, SE
Contact:

Re: Memory Leak

Unread post by Moonchild » 2022-11-29, 23:09

You are recursively calling the callback. That will lead to memory leakage. This isn't a browser bug, but rather a scripting error.

Solution: don't call setInterval() recursively from its own callback function.
"Sometimes, the best way to get what you want is to be a good person." -- Louis Rossmann
"Seek wisdom, not knowledge. Knowledge is of the past; wisdom is of the future." -- Native American proverb
"Linux makes everything difficult." -- Lyceus Anubite

User avatar
RealityRipple
Astronaut
Astronaut
Posts: 647
Joined: 2018-05-17, 02:34
Location: Los Berros Canyon, California
Contact:

Re: Memory Leak

Unread post by RealityRipple » 2022-11-30, 00:40

Did you mean to use setTimeout instead, which only fires once?

User avatar
RobertE1997
Moongazer
Moongazer
Posts: 8
Joined: 2022-11-29, 22:47

Re: Memory Leak

Unread post by RobertE1997 » 2022-11-30, 01:33

Moonchild wrote:
2022-11-29, 23:09
You are recursively calling the callback. That will lead to memory leakage. This isn't a browser bug, but rather a scripting error.

Solution: don't call setInterval() recursively from its own callback function.

Are you saying to do this? If so, I did already and still had the same issue. The reason why I modified my code to what my original post was that I was trying to figure out why memory was building up and found that the original way I did it will cause that issue, and the solution would be to use clearInterval()

Code: Select all

"use strict";



function test(){
	const xhttp = new XMLHttpRequest();
	xhttp.onload = function(){
		document.getElementById('rf_data').textContent=this.responseText;
	}

	xhttp.open("GET", "test_ajax.php");
	xhttp.send();
}

test();
id = setInterval(test, 1000);

User avatar
RobertE1997
Moongazer
Moongazer
Posts: 8
Joined: 2022-11-29, 22:47

Re: Memory Leak

Unread post by RobertE1997 » 2022-11-30, 01:35

RealityRipple wrote:
2022-11-30, 00:40
Did you mean to use setTimeout instead, which only fires once?

Nope. I need it to run every second nonstop for an indefinite length of time.

User avatar
RealityRipple
Astronaut
Astronaut
Posts: 647
Joined: 2018-05-17, 02:34
Location: Los Berros Canyon, California
Contact:

Re: Memory Leak

Unread post by RealityRipple » 2022-11-30, 03:16

RobertE1997 wrote:
2022-11-30, 01:35
RealityRipple wrote:
2022-11-30, 00:40
Did you mean to use setTimeout instead, which only fires once?

Nope. I need it to run every second nonstop for an indefinite length of time.
Exactly. It fires once, calls the function, the function makes it fire once, call the function again, etc etc. Technically it would be every second plus execution time of the called function, but it would prevent the possibility of whatever you're running from being run twice at the same time.

User avatar
Moonchild
Pale Moon guru
Pale Moon guru
Posts: 35479
Joined: 2011-08-28, 17:27
Location: Motala, SE
Contact:

Re: Memory Leak

Unread post by Moonchild » 2022-11-30, 10:21

If you need it to fire every second you use setInterval ONCE and don't cancel it, and don't call it from within the callback.
setInterval does exactly what you want if called once: it will fire the callback function every time the interval expires. Nothing else is needed.

You may also want to define the XHR object outside of the function. Since it's async by nature, creating a new XMLHttpRequest object in every time you call the callback might not result in destruction of the object. Restrict the contents of the callback to the actual get requests and handle processing the response async as well.
"Sometimes, the best way to get what you want is to be a good person." -- Louis Rossmann
"Seek wisdom, not knowledge. Knowledge is of the past; wisdom is of the future." -- Native American proverb
"Linux makes everything difficult." -- Lyceus Anubite

User avatar
RobertE1997
Moongazer
Moongazer
Posts: 8
Joined: 2022-11-29, 22:47

Re: Memory Leak

Unread post by RobertE1997 » 2022-11-30, 18:59

Moonchild wrote:
2022-11-30, 10:21
If you need it to fire every second you use setInterval ONCE and don't cancel it, and don't call it from within the callback.
setInterval does exactly what you want if called once: it will fire the callback function every time the interval expires. Nothing else is needed.

You may also want to define the XHR object outside of the function. Since it's async by nature, creating a new XMLHttpRequest object in every time you call the callback might not result in destruction of the object. Restrict the contents of the callback to the actual get requests and handle processing the response async as well.
I've tried that, the memory still continuously grows. ATM, palemoon is using RSS 130M and VSZ 616M.

Code: Select all

"use strict";

var xhttp = new XMLHttpRequest();

function test(){
        xhttp.onload = function(){
                document.getElementById('rf_data').textContent=this.responseText;
        }

        xhttp.open("GET", "test_ajax.php");
        xhttp.send();
}

setInterval(test, 1000);

User avatar
Kris_88
Keeps coming back
Keeps coming back
Posts: 933
Joined: 2021-01-26, 11:18

Re: Memory Leak

Unread post by Kris_88 » 2022-11-30, 19:44

RobertE1997 wrote:
2022-11-30, 18:59
the memory still continuously grows.
This does not necessarily mean memory leakage.

Check "about:memory" page.

User avatar
RobertE1997
Moongazer
Moongazer
Posts: 8
Joined: 2022-11-29, 22:47

Re: Memory Leak

Unread post by RobertE1997 » 2022-11-30, 20:19

Kris_88 wrote:
2022-11-30, 19:44
RobertE1997 wrote:
2022-11-30, 18:59
the memory still continuously grows.
This does not necessarily mean memory leakage.

Check "about:memory" page.
Palemoon is now using 42% of the systems memory
memory-report.json.gz
(25.29 KiB) Downloaded 6 times

User avatar
Moonchild
Pale Moon guru
Pale Moon guru
Posts: 35479
Joined: 2011-08-28, 17:27
Location: Motala, SE
Contact:

Re: Memory Leak

Unread post by Moonchild » 2022-11-30, 21:58

So you have what... 1 GB of memory or so, if that's 42%? :P
The numbers shown in your memory snapshot are well within normal operation, in fact they are pretty low for normal use.
The memory increases you're seeing in that range would just be attributed to caching and similar mechanisms.
"Sometimes, the best way to get what you want is to be a good person." -- Louis Rossmann
"Seek wisdom, not knowledge. Knowledge is of the past; wisdom is of the future." -- Native American proverb
"Linux makes everything difficult." -- Lyceus Anubite

User avatar
Kris_88
Keeps coming back
Keeps coming back
Posts: 933
Joined: 2021-01-26, 11:18

Re: Memory Leak

Unread post by Kris_88 » 2022-11-30, 22:00

The heap-unclassified value is too big.

User avatar
Moonchild
Pale Moon guru
Pale Moon guru
Posts: 35479
Joined: 2011-08-28, 17:27
Location: Motala, SE
Contact:

Re: Memory Leak

Unread post by Moonchild » 2022-11-30, 22:44

130 MB? pfft. 8-)
I wouldn't worry about memory use unless it becomes a ton larger than what is shown in that snapshot.
Also, heap-unclassified is normally not in any way related to JS.
Unfortunately since it's "unclassified" it can come from any number of different sources.
"Sometimes, the best way to get what you want is to be a good person." -- Louis Rossmann
"Seek wisdom, not knowledge. Knowledge is of the past; wisdom is of the future." -- Native American proverb
"Linux makes everything difficult." -- Lyceus Anubite

User avatar
RobertE1997
Moongazer
Moongazer
Posts: 8
Joined: 2022-11-29, 22:47

Re: Memory Leak

Unread post by RobertE1997 » 2022-11-30, 23:23

Moonchild wrote:
2022-11-30, 21:58
So you have what... 1 GB of memory or so, if that's 42%? :P
The numbers shown in your memory snapshot are well within normal operation, in fact they are pretty low for normal use.
The memory increases you're seeing in that range would just be attributed to caching and similar mechanisms.
Not even 1GB... 512MB DDR3 RAM
log_pm.txt
(18.22 KiB) Downloaded 6 times
Here is the initial crash log showing palemoon was taking tons of memory and was killed

I went ahead and disabled browser.cache.disk.enable... we will see if that changes anything

User avatar
Moonchild
Pale Moon guru
Pale Moon guru
Posts: 35479
Joined: 2011-08-28, 17:27
Location: Motala, SE
Contact:

Re: Memory Leak

Unread post by Moonchild » 2022-12-01, 09:05

512 MB of ram is insufficient to run a modern browser.
It is also completely out of scope for Pale Moon.
See also: system requirements on http://linux.palemoon.org/download/mainline/

I'm sorry but you'll just have to run your script on a little less of a low-end box.
If that is your sole purpose of running Pale Moon in an isolated environment, then you may want to try running a much older version (like 24, or maybe even 3.6) as XHR has been around for quite a while.
"Sometimes, the best way to get what you want is to be a good person." -- Louis Rossmann
"Seek wisdom, not knowledge. Knowledge is of the past; wisdom is of the future." -- Native American proverb
"Linux makes everything difficult." -- Lyceus Anubite

User avatar
RobertE1997
Moongazer
Moongazer
Posts: 8
Joined: 2022-11-29, 22:47

Re: Memory Leak

Unread post by RobertE1997 » 2022-12-02, 19:14

Moonchild wrote:
2022-12-01, 09:05
512 MB of ram is insufficient to run a modern browser.
It is also completely out of scope for Pale Moon.
See also: system requirements on http://linux.palemoon.org/download/mainline/

I'm sorry but you'll just have to run your script on a little less of a low-end box.
If that is your sole purpose of running Pale Moon in an isolated environment, then you may want to try running a much older version (like 24, or maybe even 3.6) as XHR has been around for quite a while.
I switched to Chromium and the issue isnt occurring. The memory cycles between a max of 19.5% and a low of 15.5%. Where on PM, the memory started at 20% and would rise until it got into the 60%s and then crash. The only reason I didnt use Chromium to begin with was that for some reason the browser wouldn't open. Now it does though. There has to be something wrong with PM.

vannilla
Moon Magic practitioner
Moon Magic practitioner
Posts: 2183
Joined: 2018-05-05, 13:29

Re: Memory Leak

Unread post by vannilla » 2022-12-02, 21:14

RobertE1997 wrote:
2022-12-02, 19:14
There has to be something wrong with PM.
As a rule of thumb, it is never the fault of the compiler until you can mathematically prove it to be.

In your original script, you always had at least one lingering interval that would create new XHR objects and fire up a new request in addition to the interval tracked by "id", so effectively everything was being done twice.
This is a memory leak caused not by the platform but by poor code.

The second version still had a leak in XHR objects not being necessarily released, but this is subtle and is only relevant if you operate in memory-constrained environments. Unfortunately, you do work in such an environment, so it does count as a leak because of poor code (programming for limited-resources machines is significantly different than general programming and you can't expect practices from the second category to work on the first.)

Lastly, Chromium and Pale Moon are fundamentally different in how they operate internally. Chromium splits its internals into multiple processes while Pale Moon is a single process with multiple threads.
When you examined the memory used by Chromium, which process did you look at? Was it the UI process or was it the content process executing your script? Please note that child processes are not required to have the same name as the parent process, so depending on how smart your process explorer is, simply searching for Chromium might not be enough.

Bottom line is, it has been explained that heavy memory usage is expected from Pale Moon given the circumstances, so can you prove it is not your fault instead?

Please don't take this as something personal againt you. I simply have seen a lot of valid tools, Pale Moon included, being bashed merely because people had skewed expectations or blamed the tool for some kind of failure when, in reality, they were the ones at fault (i.e. PEBKAC.)

User avatar
Kris_88
Keeps coming back
Keeps coming back
Posts: 933
Joined: 2021-01-26, 11:18

Re: Memory Leak

Unread post by Kris_88 » 2022-12-03, 20:08

PM 31.2.0.1 portable, 64bit.
I tried this script (using a local server) and did not notice the growth of memory consumption.
heap-unclassified = 18MB
I'll see what will happen in a longer time.

Code: Select all

<html>
<body>
<div id="dst"></div>
<script>
var num = 1;
function onTimer() {
  var xhr = new XMLHttpRequest();
  xhr.open("GET", "http://127.0.0.1/cgi-bin/test.cmd");
  xhr.responseType = 'text';
  xhr.onloadend = function(){
    document.getElementById('dst').textContent = xhr.response + (num++);
    setTimeout(onTimer, 1000);
  };
  xhr.send();
};
onTimer();
</script>
</body>
</html>

User avatar
Moonchild
Pale Moon guru
Pale Moon guru
Posts: 35479
Joined: 2011-08-28, 17:27
Location: Motala, SE
Contact:

Re: Memory Leak

Unread post by Moonchild » 2022-12-03, 20:18

Note, you're still making the same mistake of recursively calling the callback function here. onTimer()->xhr.onloadend->setTimeout(onTimer()) may not release resources as you expect. because the nested onTimer() will keep the parent onTimer() instance alive.
You may not see the result of that in heapunclassified because as said heapunclassifier usually has nothing to do with JS.
"Sometimes, the best way to get what you want is to be a good person." -- Louis Rossmann
"Seek wisdom, not knowledge. Knowledge is of the past; wisdom is of the future." -- Native American proverb
"Linux makes everything difficult." -- Lyceus Anubite

User avatar
Kris_88
Keeps coming back
Keeps coming back
Posts: 933
Joined: 2021-01-26, 11:18

Re: Memory Leak

Unread post by Kris_88 » 2022-12-03, 20:27

No, I do not see a possible leak here. I do not call the onTimer recursively, but only register the function as a callback for the setTimeout.
Moonchild wrote:
2022-12-03, 20:18
You may not see the result of that in heapunclassified because as said heapunclassifier usually has nothing to do with JS.
We do not know where there may be a leak. Not necessarily in JS. The rendering in the ARM version may be to blame. The script constantly updates the contents of the DIV, which usually does not happen in conventional browsing.

Locked