This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author vstinner
Recipients vstinner
Date 2022-01-23.00:29:31
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1642897771.95.0.216870338714.issue46476@roundup.psfhosted.org>
In-reply-to
Content
Python leaks around 66 memory blocks at exit. Most of them are allocated by _Py_Quicken() of Python/specialize.c.

int
_Py_Quicken(PyCodeObject *code) {
    ...
    SpecializedCacheOrInstruction *quickened = allocate(entry_count, instr_count);
    ...
    code->co_quickened = quickened;
    ...
    return 0;
}

The memory is stored in PyCodeObject.co_quickened member. This member *is* cleared by the code object deallocator function, code_dealloc():

static void
code_dealloc(PyCodeObject *co)
{
    ...
    if (co->co_quickened) {
        PyMem_Free(co->co_quickened);
        _Py_QuickenedCount--;
    }
    ...
}

I read recently that deepfreeze creates "immortal" code objects (refcount of 999999999). I guess that it's related.


I used Valgrind to look for memory leaked by Python at exit:

$ PYTHONMALLOC=malloc valgrind --show-leak-kinds=all --leak-check=full --log-file=valgrind.log --num-callers=50 ./python -c pass

Extract of valgrind.log:

==1266888== 5,528 bytes in 13 blocks are still reachable in loss record 33 of 33
==1266888==    at 0x484186F: malloc (vg_replace_malloc.c:381)
==1266888==    by 0x544DBC: _PyMem_RawMalloc (obmalloc.c:100)
==1266888==    by 0x545B13: PyMem_Malloc (obmalloc.c:618)
==1266888==    by 0x6AAE6F: allocate (specialize.c:231)
==1266888==    by 0x6AB3F0: _Py_Quicken (specialize.c:420)
==1266888==    by 0x622CE7: _Py_IncrementCountAndMaybeQuicken (pycore_code.h:152)
==1266888==    by 0x626315: _PyEval_EvalFrameDefault (ceval.c:1792)
==1266888==    by 0x622B13: _PyEval_EvalFrame (pycore_ceval.h:53)
==1266888==    ...
==1266888== 
==1266888== LEAK SUMMARY:
==1266888==    definitely lost: 0 bytes in 0 blocks
==1266888==    indirectly lost: 0 bytes in 0 blocks
==1266888==      possibly lost: 0 bytes in 0 blocks
==1266888==    still reachable: 24,240 bytes in 66 blocks
==1266888==         suppressed: 0 bytes in 0 blocks


See also bpo-46449: "Deep-freezed modules create inconsistency in sys.gettotalrefcount() (_Py_Reftotal)".
History
Date User Action Args
2022-01-23 00:29:31vstinnersetrecipients: + vstinner
2022-01-23 00:29:31vstinnersetmessageid: <1642897771.95.0.216870338714.issue46476@roundup.psfhosted.org>
2022-01-23 00:29:31vstinnerlinkissue46476 messages
2022-01-23 00:29:31vstinnercreate