std::weak_ptr может удерживать память даже при expired() == true.Причина в
std::make_shared: обычно он размещает объект и управляющий блок в одной аллокации.В примере на скриншоте массив на 16 МиБ находится прямо внутри
Blob. После удаления последнего shared_ptr:* деструктор объекта вызывается;
*
expired() возвращает true;* общий блок памяти остаётся выделенным, пока существует хотя бы один
weak_ptr.После сброса последней слабой ссылки блок можно освободить.
Что делать: удалять протухшие ссылки из долгоживущих кешей. Для крупных объектов также можно рассмотреть отдельную аллокацию через
std::shared_ptr<Blob>(new Blob()).Нюанс касается размера самого объекта. Если данные хранятся в обычном
std::vector, его отдельный буфер освобождается при вызове деструктора.[Разбор от Microsoft](https://devblogs.microsoft.com/oldnewthing/20230815-00/?p=108602)
