Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

support pypy - add gc.collect() #2

Open
mattip opened this issue Apr 28, 2017 · 3 comments
Open

support pypy - add gc.collect() #2

mattip opened this issue Apr 28, 2017 · 3 comments

Comments

@mattip
Copy link

mattip commented Apr 28, 2017

Thanks for this code

PyPy requires forcing a collection before measuring memory usage after a test. For me it was enough to modify the runtest code:

is_pypy = '__pypy__' in sys.builtin_module_names

@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_call(item):
    if configuration.getoption('memory_usage') or configuration.getini('memory_usage'):
        if not is_pypy:
            gc.disable()
        state.before_call = get_memory(state.process)
        yield
        if is_pypy:
            gc.collect();
        state.after_call = get_memory(state.process)
        if not is_pypy:
            gc.enable()
    else:
        yield

would you rather get this as a pull request?

@eli-b
Copy link
Owner

eli-b commented Apr 28, 2017

Hi Matti! Thanks for your interest.

I'll be glad to work this into the code.

Could you explain why PyPy requires forcing a collection before measuring memory usage? I'm curious.

@mattip
Copy link
Author

mattip commented Apr 28, 2017

First CPython: its refcount garbage collection is triggered on exiting a frame, in a predictable and consistent way
Now PyPy: it uses a modified mark-and-sweep strategy, triggered by the amount of spare room in a memory "nursery" available for new allocations. In many situations, the nursery is large enough to run a complete program without ever triggering a garbage collection, especially in small bits of code like tests

So if you want to clean out all the old objects, on CPython it is sufficient to exit a function, but on PyPy you need to explicitly ask for a GC collection cycle

More about this can be found on the PyPy doc site http://pypy.readthedocs.io/en/latest/gc_info.html or on the RPython doc site http://rpython.readthedocs.io/en/latest/garbage_collection.html

@eli-b
Copy link
Owner

eli-b commented Apr 28, 2017

Wow! Thanks for the thorough answer.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants