Vì vậy, giả sử mã C/C++ phân bổ một số bộ nhớ và trả về một con trỏ đến nó.Python: hành vi thu gom rác thải với ctypes
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
void Allocate(void **p) {
int N=2048;
*p=malloc(N);
}
#ifdef __cplusplus
}
#endif
Tôi hy vọng rằng đó là trách nhiệm của tôi để giải phóng khối bộ nhớ đó. Bây giờ giả sử tôi biên dịch nó thành một thư viện được chia sẻ và gọi nó từ Python với ctypes, nhưng không giải phóng bộ nhớ đó một cách rõ ràng.
import ctypes
from ctypes import cdll, Structure, byref
external_lib = cdll.LoadLibrary('libtest.so.1.0')
ptr=ctypes.c_void_p(0)
external_lib.Allocate(ctypes.byref(ptr))
Nếu tôi chạy tập lệnh này với valgrind, tôi bị rò rỉ bộ nhớ 2048 byte nếu tôi biên dịch test.cpp không có cờ '-O3'. Nhưng nếu tôi biên dịch nó với lá cờ '-O3', thì tôi không bị rò rỉ bộ nhớ.
Nó không thực sự là một vấn đề - tôi sẽ luôn luôn cẩn thận để giải phóng một cách rõ ràng bất kỳ bộ nhớ nào tôi phân bổ. Nhưng tôi tò mò về hành vi này đến từ đâu.
Tôi đã thử nghiệm điều này bằng tập lệnh sau trong linux.
g++ -Wall -c -fPIC -fno-common test.cpp -o libtest1.o
g++ -shared -Wl,-soname,libtest1.so.1 -o libtest1.so.1.0 libtest1.o
g++ -O3 -Wall -c -fPIC -fno-common test.cpp -o libtest2.o
g++ -shared -Wl,-soname,libtest2.so.1 -o libtest2.so.1.0 libtest2.o
valgrind python test1.py &> report1
valgrind python test2.py &> report2
với sản lượng sau
Report1:
==27875== LEAK SUMMARY:
==27875== definitely lost: 2,048 bytes in 1 blocks
==27875== indirectly lost: 0 bytes in 0 blocks
==27875== possibly lost: 295,735 bytes in 1,194 blocks
==27875== still reachable: 744,633 bytes in 5,025 blocks
==27875== suppressed: 0 bytes in 0 blocks
Report2:
==27878== LEAK SUMMARY:
==27878== definitely lost: 0 bytes in 0 blocks
==27878== indirectly lost: 0 bytes in 0 blocks
==27878== possibly lost: 295,735 bytes in 1,194 blocks
==27878== still reachable: 746,681 bytes in 5,026 blocks
==27878== suppressed: 0 bytes in 0 blocks
Tôi đã theo bước của bạn và kết quả là thú vị. Với 'Python 3.3.2' hai báo cáo đều cho rò rỉ với 2048 byte, tuy nhiên với' Python 2.7.5' thì không có rò rỉ nào với báo cáo. Thử nghiệm trong 'Linux 3.11.4 x86_64' với 'gcc 4.8.1 20130725' – starrify