[pypy-commit] cffi default: Document the missing add_memory_pressure in PyPy <= 5.6
arigo
pypy.commits at gmail.com
Fri Mar 10 03:05:19 EST 2017
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r2897:0cfa29f0cd5e
Date: 2017-03-10 08:37 +0100
http://bitbucket.org/cffi/cffi/changeset/0cfa29f0cd5e/
Log: Document the missing add_memory_pressure in PyPy <= 5.6
diff --git a/doc/source/ref.rst b/doc/source/ref.rst
--- a/doc/source/ref.rst
+++ b/doc/source/ref.rst
@@ -501,23 +501,31 @@
# then replace `p = ffi.new("char[]", bigsize)` with:
p = new_nonzero("char[]", bigsize)
-Note anyway that it might be a better idea to use explicit calls to
-``lib.malloc()`` and ``lib.free()``, because the memory returned by
-``new()`` or ``new_allocator()()`` is only freed when the garbage
-collector runs (i.e. not always instantly after the reference to the
-object goes away, particularly but not only on PyPy). Example::
+**NOTE:** the following is a general warning that applies particularly
+(but not only) to PyPy versions 5.6 or older (PyPy > 5.6 attempts to
+account for the memory returned by ``ffi.new()`` or a custom allocator;
+and CPython uses reference counting). If you do large allocations, then
+there is no hard guarantee about when the memory will be freed. You
+should avoid both ``new()`` and ``new_allocator()()`` if you want to be
+sure that the memory is promptly released, e.g. before you allocate more
+of it.
- ffibuilder.cdef("""
- void *malloc(size_t size);
- void free(void *ptr);
- """)
+An alternative is to declare and call the C ``malloc()`` and ``free()``
+functions, or some variant like ``mmap()`` and ``munmap()``. Then you
+control exactly when the memory is allocated and freed. For example,
+add these two lines to your existing ``ffibuilder.cdef()``::
- # then in your code:
- p = lib.malloc(bigsize)
- try:
- ...
- finally:
- lib.free(p)
+ void *malloc(size_t size);
+ void free(void *ptr);
+
+and then call these two functions manually::
+
+ p = lib.malloc(bigsize)
+ try:
+ my_array = ffi.cast("some_other_type_than_void*", p)
+ ...
+ finally:
+ lib.free(p)
ffi.init_once()
diff --git a/doc/source/whatsnew.rst b/doc/source/whatsnew.rst
--- a/doc/source/whatsnew.rst
+++ b/doc/source/whatsnew.rst
@@ -57,6 +57,10 @@
compare equal to ``ffi.cast("unsigned int", -1)``: it compares
smaller, because ``-1 < 4294967295``.
+* PyPy: ``ffi.new()`` and ``ffi.new_allocator()()`` did not record
+ "memory pressure", causing the GC to run too infrequently if you call
+ ``ffi.new()`` very often and/or with large arrays. Fixed in PyPy 5.7.
+
v1.9
====
More information about the pypy-commit
mailing list