-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Huge memory usage with jslib URL #1851
Comments
Hi @zerda , The problem doesn't seem to be with the jslib URL lib, but with your script and the fact that both golang (the language k6 is written) and JavaScript a garbage-collected languages. This means that if you generate objects they will not be cleaned up by you but by something called a garbage collector. In your particular script, all you do is generate object so the only thing that is truly exercised is whether k6 can generate objects faster than the garbage collector can keep up ... and the garbage collector will at some point find equilibrium between letting the problem run (at all) and there not being too much garbage. If you add an and to prove to you that this has nothing to do with the lib try running: export default function() {
var s = {
key: "value"
}
} you will notice that the memory usage will go up (to around 6GB over 1 minute for me). And this is basically what the code that you provide does ... just with a bunch more steps and with a much bigger object. |
Thanks for your excellent explanation. I was trying to simplify this issue, but it's seems cause a little confusion. In real world, I have extracted some parts from URL object to build a request signature. When running with 1000uv 5mins, It's exhausted all 32GiB memory. // still a poc
import { URL } from 'https://jslib.k6.io/url/1.0.0/index.js';
function buildMessage(method, pathName, queryParams, requestHeaders, requestBody) {
// emitted
}
export default function() {
var url = new URL('https://httpbin.test.k6.io/');
var method = 'GET';
var headers = {};
var body = "";
const message = buildMessage(method, url.pathname, url.searchParams, headers, body);
} Replace URL class with this incompleted but working method, the memory usage is about 6GiB and stop growing. // simpified version of URL & URLSearchParams, for better memory usage.
function getUrlParts(url) {
if (url === null || url === undefined || url === '') return '';
const [left, querystring] = url.replace(/https*:\/\//, '').split('?');
let queryParams = {};
if (querystring) {
queryParams = querystring.split('&').reduce(function(params, param) {
param = param.split('=');
if (Number.isInteger(parseInt(param[1])) && parseInt(param[1]) == param[1]) {
params[param[0]] = parseInt(param[1]);
} else {
params[param[0]] = decodeURI(param[1]);
}
}, {});
}
return {
path: left.substring(left.indexOf('/')),
queryParams
};
}
function buildMessage(method, pathName, queryParams, requestHeaders, requestBody) {
// emitted
}
export default function() {
var urlParts = getUrlParts('https://httpbin.test.k6.io/');
var method = 'GET';
var headers = {};
var body = "";
const message = buildMessage(method, urlParts.path, urlParts.queryParams, headers, body);
} |
I still don't see an actual HTTP request being made in your second example, so I'm guessing the 32+GB/6GB still has more to do with GC pressure than with realistic memory usage... But to respond to your question, we are probably going to get a native (i.e. Go, not JS) replacement of the |
I made a point of this issue in #991 (comment), so I'll close it, considering we track the adoption of a Go |
Environment
Expected Behavior
Stable and low memory usage with URL object.
Actual Behavior
With a simple script, memory usage is about 5.8GiB by 1000uv and 10s, and 7.5GiB by 1000uv and 30s.
It's about 1/2 memory when script is transformed to es5, and running with
--compatibility-mode=base
option.Steps to Reproduce the Problem
The text was updated successfully, but these errors were encountered: