关闭与数据库的连接时不会释放内存(C,postgres - libpq)
Memory is not freed when connection to database is closed (C, postgres - libpq)
如果您只用以下两行创建一个程序:
PGconn *conn = PQconnectdb("user=dbtest password=dbtest dbname=testdb host=localhost port=5432");
PQfinish(conn);
并且 运行 它通过 valgrind 像这样:
valgrind --leak-check=full --show-leak-kinds=all ./program
你看到这个:
==25388== Memcheck, a memory error detector
==25388== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==25388== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==25388== Command: ./program
==25388==
==25388==
==25388== HEAP SUMMARY:
==25388== in use at exit: 109 bytes in 2 blocks
==25388== total heap usage: 6,948 allocs, 6,946 frees, 666,147 bytes allocated
==25388==
==25388== 13 bytes in 1 blocks are still reachable in loss record 1 of 2
==25388== at 0x483874F: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==25388== by 0x4CB0635: CRYPTO_strdup (in /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1)
==25388== by 0x4BD8AFB: BIO_meth_new (in /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1)
==25388== by 0x488BE8B: ??? (in /usr/lib/x86_64-linux-gnu/libpq.so.5.11)
==25388== by 0x488D19C: ??? (in /usr/lib/x86_64-linux-gnu/libpq.so.5.11)
==25388== by 0x487507F: PQconnectPoll (in /usr/lib/x86_64-linux-gnu/libpq.so.5.11)
==25388== by 0x4875E3E: ??? (in /usr/lib/x86_64-linux-gnu/libpq.so.5.11)
==25388== by 0x4878CD7: PQconnectdb (in /usr/lib/x86_64-linux-gnu/libpq.so.5.11)
==25388== by 0x109158: main (in /workspace/test/src/program)
==25388==
==25388== 96 bytes in 1 blocks are still reachable in loss record 2 of 2
==25388== at 0x483874F: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==25388== by 0x4CA70E8: CRYPTO_zalloc (in /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1)
==25388== by 0x4BD8ADF: BIO_meth_new (in /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1)
==25388== by 0x488BE8B: ??? (in /usr/lib/x86_64-linux-gnu/libpq.so.5.11)
==25388== by 0x488D19C: ??? (in /usr/lib/x86_64-linux-gnu/libpq.so.5.11)
==25388== by 0x487507F: PQconnectPoll (in /usr/lib/x86_64-linux-gnu/libpq.so.5.11)
==25388== by 0x4875E3E: ??? (in /usr/lib/x86_64-linux-gnu/libpq.so.5.11)
==25388== by 0x4878CD7: PQconnectdb (in /usr/lib/x86_64-linux-gnu/libpq.so.5.11)
==25388== by 0x109158: main (in /workspace/test/src/program)
==25388==
==25388== LEAK SUMMARY:
==25388== definitely lost: 0 bytes in 0 blocks
==25388== indirectly lost: 0 bytes in 0 blocks
==25388== possibly lost: 0 bytes in 0 blocks
==25388== still reachable: 109 bytes in 2 blocks
==25388== suppressed: 0 bytes in 0 blocks
==25388==
==25388== For counts of detected and suppressed errors, rerun with: -v
==25388== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
我注意到打开和关闭更多连接似乎不会影响丢失或仍可访问的字节数。
我对C不是很了解,只好请教:
怎么还有字节可以访问?当我关闭与数据库的连接时,我希望一切都被释放。
这些分配是在 libcrypto
的初始化期间执行的,postgresql 客户端使用它来通过 SSL/TLS 与服务器通信。该初始化只进行一次;打开多少连接并不重要。 (但是,如果连接使用不同的密码,可能会有额外的初始化。)
Libcrypto 确实提供了可用于释放初始化期间分配的存储空间的接口。这些记录在 OpenSSL documentation 中。所以你可以尝试将它们添加到你的代码中。但是,老实说,除了让 valgrind 报告更清晰之外,这真的没关系。
如果您只用以下两行创建一个程序:
PGconn *conn = PQconnectdb("user=dbtest password=dbtest dbname=testdb host=localhost port=5432");
PQfinish(conn);
并且 运行 它通过 valgrind 像这样:
valgrind --leak-check=full --show-leak-kinds=all ./program
你看到这个:
==25388== Memcheck, a memory error detector
==25388== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==25388== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==25388== Command: ./program
==25388==
==25388==
==25388== HEAP SUMMARY:
==25388== in use at exit: 109 bytes in 2 blocks
==25388== total heap usage: 6,948 allocs, 6,946 frees, 666,147 bytes allocated
==25388==
==25388== 13 bytes in 1 blocks are still reachable in loss record 1 of 2
==25388== at 0x483874F: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==25388== by 0x4CB0635: CRYPTO_strdup (in /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1)
==25388== by 0x4BD8AFB: BIO_meth_new (in /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1)
==25388== by 0x488BE8B: ??? (in /usr/lib/x86_64-linux-gnu/libpq.so.5.11)
==25388== by 0x488D19C: ??? (in /usr/lib/x86_64-linux-gnu/libpq.so.5.11)
==25388== by 0x487507F: PQconnectPoll (in /usr/lib/x86_64-linux-gnu/libpq.so.5.11)
==25388== by 0x4875E3E: ??? (in /usr/lib/x86_64-linux-gnu/libpq.so.5.11)
==25388== by 0x4878CD7: PQconnectdb (in /usr/lib/x86_64-linux-gnu/libpq.so.5.11)
==25388== by 0x109158: main (in /workspace/test/src/program)
==25388==
==25388== 96 bytes in 1 blocks are still reachable in loss record 2 of 2
==25388== at 0x483874F: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==25388== by 0x4CA70E8: CRYPTO_zalloc (in /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1)
==25388== by 0x4BD8ADF: BIO_meth_new (in /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1)
==25388== by 0x488BE8B: ??? (in /usr/lib/x86_64-linux-gnu/libpq.so.5.11)
==25388== by 0x488D19C: ??? (in /usr/lib/x86_64-linux-gnu/libpq.so.5.11)
==25388== by 0x487507F: PQconnectPoll (in /usr/lib/x86_64-linux-gnu/libpq.so.5.11)
==25388== by 0x4875E3E: ??? (in /usr/lib/x86_64-linux-gnu/libpq.so.5.11)
==25388== by 0x4878CD7: PQconnectdb (in /usr/lib/x86_64-linux-gnu/libpq.so.5.11)
==25388== by 0x109158: main (in /workspace/test/src/program)
==25388==
==25388== LEAK SUMMARY:
==25388== definitely lost: 0 bytes in 0 blocks
==25388== indirectly lost: 0 bytes in 0 blocks
==25388== possibly lost: 0 bytes in 0 blocks
==25388== still reachable: 109 bytes in 2 blocks
==25388== suppressed: 0 bytes in 0 blocks
==25388==
==25388== For counts of detected and suppressed errors, rerun with: -v
==25388== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
我注意到打开和关闭更多连接似乎不会影响丢失或仍可访问的字节数。
我对C不是很了解,只好请教:
怎么还有字节可以访问?当我关闭与数据库的连接时,我希望一切都被释放。
这些分配是在 libcrypto
的初始化期间执行的,postgresql 客户端使用它来通过 SSL/TLS 与服务器通信。该初始化只进行一次;打开多少连接并不重要。 (但是,如果连接使用不同的密码,可能会有额外的初始化。)
Libcrypto 确实提供了可用于释放初始化期间分配的存储空间的接口。这些记录在 OpenSSL documentation 中。所以你可以尝试将它们添加到你的代码中。但是,老实说,除了让 valgrind 报告更清晰之外,这真的没关系。