@@ -298,67 +298,12 @@ default configuration of a single Python context (as is used when running the
298
298
launcher). For better sharing of warmup and where absolutely best peak
299
299
performance is not needed, contexts can be configured with a shared engine and
300
300
the ASTs will be shared across contexts. However, that implies we * must* not
301
- store any user objects strongly in the ASTs. Here is a query to find any such
302
- leaks where a PythonObject is reacheable from any kind of Truffle AST Node
303
- subinstance in VisualVM:
304
-
305
- findLeaks("com.oracle.graal.python.builtins.objects.object.PythonObject", "com.oracle.truffle.api.nodes.Node")
306
-
307
- function findLeaks(to, from) {
308
- var objs = heap.objects(to, true)
309
- var leaks = []
310
- var path = []
311
- var cutOffPath = false
312
-
313
- while (objs.hasMoreElements() && leaks.length < 100) {
314
- var o = objs.nextElement()
315
- path = []
316
- cutOffPath = false
317
- if (isReferencedFromAtMaxDepth(o, 20)) {
318
- if (!cutOffPath) {
319
- leaks.push(o)
320
- }
321
- }
322
- }
323
- return leaks
324
-
325
- function isReferencedFromAtMaxDepth(obj, limit) {
326
- var refs = referrers(obj)
327
- while (refs.hasMoreElements()) {
328
- var o = refs.nextElement()
329
- var refClass = classof(o)
330
- var cutOffHere = false
331
- while (refClass != null) {
332
- if (refClass.name == from) {
333
- leaks.push(classof(o).name)
334
- return true
335
- } else if (refClass.name == "java.lang.ref.WeakReference" ||
336
- refClass.name == "java.lang.ref.SoftReference" ||
337
- refClass.name == "java.lang.ref.PhantomReference") {
338
- // any weak reference is fine
339
- return false;
340
- } else if (refClass.name == to) {
341
- // we have found another `to` object along the path, use this one as the shorter path
342
- cutOffHere = true
343
- }
344
- refClass = refClass.superclass
345
- }
346
- if (limit > 0) {
347
- if (isReferencedFromAtMaxDepth(o, limit - 1)) {
348
- if (!cutOffPath) {
349
- if (cutOffHere) {
350
- cutOffPath = true
351
- leaks.push(o)
352
- } else {
353
- leaks.push(classof(o).name)
354
- }
355
- }
356
- return true
357
- }
358
- }
359
- }
360
- return false
361
- }
362
- }
363
-
364
- Running such a query on a multi-context heap should yield no results.
301
+ store any user objects strongly in the ASTs. We test that we have no
302
+ PythonObjects alive after a Context is closed that are run as part of our JUnit
303
+ tests. These can be run by themselves, for example, like so:
304
+
305
+ $ mx python-leak-test --lang python --shared-engine --code 'import site, json' --forbidden-class com.oracle.graal.python.builtins.objects.object.PythonObject --keep-dump
306
+
307
+ The ` --keep-dump ` option will print the heapdump location and leave the file
308
+ there rather than deleting it. It can then be opened for example with VisualVM
309
+ to check for the paths of any leaked object, if there are any.
0 commit comments