PythonMonkey icon indicating copy to clipboard operation
PythonMonkey copied to clipboard

Leak in StrType::proxifyString

Open philippedistributive opened this issue 5 months ago • 3 comments

Issue type

Bug

How did you install PythonMonkey?

None

OS platform and distribution

No response

Python version (python --version)

No response

PythonMonkey version (pip show pythonmonkey)

No response

Bug Description

Get sanitizer leak report:

================================================================= ==39075==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 12352 byte(s) in 386 object(s) allocated from: #0 0x7e75e44fc698 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:95 #1 0x7e75e01956d1 in StrType::proxifyString(JSContext*, JS::HandleJS::Value) /home/philippe/Sources/PythonMonkey/src/StrType.cc:114 #2 0x7e75e0196348 in StrType::getPyObject(JSContext*, JS::HandleJS::Value) /home/philippe/Sources/PythonMonkey/src/StrType.cc:194 #3 0x7e75e01b1f45 in pyTypeFactory(JSContext*, JS::HandleJS::Value) /home/philippe/Sources/PythonMonkey/src/pyTypeFactory.cc:56 #4 0x7e75e013a456 in getKey /home/philippe/Sources/PythonMonkey/src/JSObjectProxy.cc:124 #5 0x7e75e013af9d in JSObjectProxyMethodDefinitions::JSObjectProxy_get_subscript(JSObjectProxy*, _object*) /home/philippe/Sources/PythonMonkey/src/JSObjectProxy.cc:162 #6 0x7e75e3f45d0c in PyMapping_GetItemString Objects/abstract.c:2353

code sample:

#!/usr/bin/env python3 """ Works at 1020000 elements, OOMs at 1030000 elements... """

import pythonmonkey as pm

oomer = pm.eval(""" function oomer() { let arr_size; // change array size to different values arr_size = 1020000; // success! arr_size = 1030000; // OOMs (ON MY SYSTEM! - maybe you'll have to up it to OOM on yours!)

const bigArray = []; for (let i = 0; i < arr_size; i++) bigArray.push(i + 0.1 / (i + 0.123456)); // randomish floats, fattened up by json.stringify A LOT later

//let seed = 1; bigArray.sort(() => (Math.sin(seed++) * 10000) % 1 - 0.5); // TODO unnecessary, remove later

// these initial values don't really matter per se, it's more just about how they're serialized console.log(Array length: ${bigArray.length}); console.log(Array bytes : ${bigArray.length * 8}); // 8 bytes per js number??? console.log(Array MB : ${bigArray.length * 8 / 1000000});

// The following code is baed off of encodeJobValueList in dcp-client/job/index.js const jsonedElementsArray = []; for (let i = 0; i < bigArray.length; i++) { jsonedElementsArray.push(JSON.stringify(bigArray[i]));

// logging
if (i % 10000 === 0 && i > 600000) // skip first 600000 then only print every 10000 elements
  console.log(i, ' -- ', bigArray[i]);

}

// now we calculate the total length of all the strings in the array and see how much memory they use console.log(JSONed Array length: ${jsonedElementsArray.length}); console.log(JSONed Array bytes : ${jsonedElementsArray.reduce((acc, str) => acc + str.length, 0) * 2}); // 2 bytes per character console.log(JSONed Array MB : ${jsonedElementsArray.reduce((acc, str) => acc + str.length, 0) * 2 / 1000000}); } oomer """)

oomer()

Standalone code to reproduce the issue

No response

Relevant log output or backtrace

No response

Additional info if applicable

No response

What branch of PythonMonkey were you developing on? (If applicable)

No response

philippedistributive avatar Aug 28 '24 15:08 philippedistributive