Skip to content

Commit 2c51a07

Browse files
sipafanquake
authored andcommitted
Do not use std::vector = {} to release memory
Github-Pull: bitcoin#28452 Rebased-From: 3fcd7fc
1 parent 887cbfc commit 2c51a07

File tree

3 files changed

+46
-2
lines changed

3 files changed

+46
-2
lines changed

src/headerssync.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <pow.h>
88
#include <timedata.h>
99
#include <util/check.h>
10+
#include <util/vector.h>
1011

1112
// The two constants below are computed using the simulation script on
1213
// https://gist.github.com/sipa/016ae445c132cdf65a2791534dfb7ae1
@@ -51,9 +52,9 @@ HeadersSyncState::HeadersSyncState(NodeId id, const Consensus::Params& consensus
5152
void HeadersSyncState::Finalize()
5253
{
5354
Assume(m_download_state != State::FINAL);
54-
m_header_commitments = {};
55+
ClearShrink(m_header_commitments);
5556
m_last_header_received.SetNull();
56-
m_redownloaded_headers = {};
57+
ClearShrink(m_redownloaded_headers);
5758
m_redownload_buffer_last_hash.SetNull();
5859
m_redownload_buffer_first_prev_hash.SetNull();
5960
m_process_all_remaining_headers = false;

src/test/util_tests.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1791,4 +1791,29 @@ BOOST_AUTO_TEST_CASE(util_WriteBinaryFile)
17911791
BOOST_CHECK(valid);
17921792
BOOST_CHECK_EQUAL(actual_text, expected_text);
17931793
}
1794+
1795+
BOOST_AUTO_TEST_CASE(clearshrink_test)
1796+
{
1797+
{
1798+
std::vector<uint8_t> v = {1, 2, 3};
1799+
ClearShrink(v);
1800+
BOOST_CHECK_EQUAL(v.size(), 0);
1801+
BOOST_CHECK_EQUAL(v.capacity(), 0);
1802+
}
1803+
1804+
{
1805+
std::vector<bool> v = {false, true, false, false, true, true};
1806+
ClearShrink(v);
1807+
BOOST_CHECK_EQUAL(v.size(), 0);
1808+
BOOST_CHECK_EQUAL(v.capacity(), 0);
1809+
}
1810+
1811+
{
1812+
std::deque<int> v = {1, 3, 3, 7};
1813+
ClearShrink(v);
1814+
BOOST_CHECK_EQUAL(v.size(), 0);
1815+
// std::deque has no capacity() we can observe.
1816+
}
1817+
}
1818+
17941819
BOOST_AUTO_TEST_SUITE_END()

src/util/vector.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,22 @@ inline V Cat(V v1, const V& v2)
4949
return v1;
5050
}
5151

52+
/** Clear a vector (or std::deque) and release its allocated memory. */
53+
template<typename V>
54+
inline void ClearShrink(V& v) noexcept
55+
{
56+
// There are various ways to clear a vector and release its memory:
57+
//
58+
// 1. V{}.swap(v)
59+
// 2. v = V{}
60+
// 3. v = {}; v.shrink_to_fit();
61+
// 4. v.clear(); v.shrink_to_fit();
62+
//
63+
// (2) does not appear to release memory in glibc debug mode, even if v.shrink_to_fit()
64+
// follows. (3) and (4) rely on std::vector::shrink_to_fit, which is only a non-binding
65+
// request. Therefore, we use method (1).
66+
67+
V{}.swap(v);
68+
}
69+
5270
#endif // BITCOIN_UTIL_VECTOR_H

0 commit comments

Comments
 (0)