Commit c8a5d32
committed
Fix memory leak on short-lived reactive pipelines
Derived rx nodes registered their invalidation callbacks
(_invalidate_obj/_invalidate_current) on their source parameter as strong
bound-method references. Since the source is typically long-lived, this
pinned every derived node — and anything it captured, such as large arrays
— alive indefinitely, with no way to reclaim it.
Wrap the invalidation callbacks in a weakref.WeakMethod (_WeakInvalidator)
and register a finalizer to prune the watcher once the node is collected.
The node now becomes garbage collectable as soon as it is no longer
referenced, and the source's watcher list no longer grows without bound.
This changes no observable public API behavior: while an expression is
referenced it behaves exactly as before, and watch()/_watch() are
untouched. Only a node that was previously unreachable-but-uncollectable
(pinned solely by the source's internal watcher) is now reclaimed.
Assisted-by: Claude:claude-opus-4-81 parent 2ec0571 commit c8a5d32
2 files changed
Lines changed: 75 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
94 | 94 | | |
95 | 95 | | |
96 | 96 | | |
| 97 | + | |
97 | 98 | | |
98 | 99 | | |
99 | 100 | | |
| |||
1359 | 1360 | | |
1360 | 1361 | | |
1361 | 1362 | | |
| 1363 | + | |
| 1364 | + | |
| 1365 | + | |
| 1366 | + | |
| 1367 | + | |
| 1368 | + | |
| 1369 | + | |
| 1370 | + | |
| 1371 | + | |
| 1372 | + | |
| 1373 | + | |
| 1374 | + | |
| 1375 | + | |
| 1376 | + | |
| 1377 | + | |
| 1378 | + | |
| 1379 | + | |
| 1380 | + | |
| 1381 | + | |
| 1382 | + | |
| 1383 | + | |
| 1384 | + | |
| 1385 | + | |
| 1386 | + | |
| 1387 | + | |
| 1388 | + | |
| 1389 | + | |
| 1390 | + | |
| 1391 | + | |
| 1392 | + | |
| 1393 | + | |
| 1394 | + | |
| 1395 | + | |
1362 | 1396 | | |
1363 | 1397 | | |
1364 | 1398 | | |
| |||
1712 | 1746 | | |
1713 | 1747 | | |
1714 | 1748 | | |
1715 | | - | |
| 1749 | + | |
1716 | 1750 | | |
1717 | | - | |
| 1751 | + | |
| 1752 | + | |
| 1753 | + | |
| 1754 | + | |
| 1755 | + | |
| 1756 | + | |
| 1757 | + | |
| 1758 | + | |
| 1759 | + | |
| 1760 | + | |
| 1761 | + | |
| 1762 | + | |
| 1763 | + | |
1718 | 1764 | | |
1719 | 1765 | | |
1720 | 1766 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
| 2 | + | |
2 | 3 | | |
3 | 4 | | |
4 | 5 | | |
5 | 6 | | |
| 7 | + | |
6 | 8 | | |
7 | 9 | | |
8 | 10 | | |
| |||
1029 | 1031 | | |
1030 | 1032 | | |
1031 | 1033 | | |
| 1034 | + | |
| 1035 | + | |
| 1036 | + | |
| 1037 | + | |
| 1038 | + | |
| 1039 | + | |
| 1040 | + | |
| 1041 | + | |
| 1042 | + | |
| 1043 | + | |
| 1044 | + | |
| 1045 | + | |
| 1046 | + | |
| 1047 | + | |
| 1048 | + | |
| 1049 | + | |
| 1050 | + | |
| 1051 | + | |
| 1052 | + | |
| 1053 | + | |
| 1054 | + | |
| 1055 | + | |
| 1056 | + | |
| 1057 | + | |
| 1058 | + | |
0 commit comments