内存无法释放std :: list <std :: shared_ptr <std :: string >> C ++

阿米丝·金​​萨卡(Amith Chinthaka)

我正在填充字符串共享指针的列表。在程序的某个时刻,我清除了列表。但是,即使我调用clear()list函数,程序的内存消耗也不会减少知道为什么吗?

#include <memory>
#include <string>
#include <list>
#include <iostream>

int main()
{
    std::string text = "                                                            \
        PREFACE                                                                     \
                                                                                    \
        Most of the adventures recorded in this book really occurred; one or two    \
        were experiences of my own, the rest those of boys who were schoolmates     \
        of mine. Huck Finn is drawn from life; Tom Sawyer also, but not from an     \
        individual--he is a combination of the characteristics of three boys whom   \
        I knew, and therefore belongs to the composite order of architecture.       \
                                                                                    \
        The odd superstitions touched upon were all prevalent among children and    \
        slaves in the West at the period of this story--that is to say, thirty or   \
        forty years ago.                                                            \
                                                                                    \
        Although my book is intended mainly for the entertainment of boys and       \
        girls, I hope it will not be shunned by men and women on that account,      \
        for part of my plan has been to try to pleasantly remind adults of what     \
        they once were themselves, and of how they felt and thought and talked,     \
        and what queer enterprises they sometimes engaged in.                       \
    ";

    std::list<std::shared_ptr<std::string>> data;
    for (auto i = 0u; i < 999999; ++i) {
        data.push_back(std::make_shared<std::string>(text));
    }

    std::cout << "Data loaded. Press any key to continue...";
    std::cin.get();

    data.clear(); // memory does not reduce
    std::cout << "Data unloaded. Press any key to continue...";
    std::cin.get();

    std::cout << "Container size:" << data.size() << std::endl;
    std::cout << "Press any key to exit...";
    std::cin.get();

    return 0;
}

我正在WSL上调试。我使用了Linux top(在WSL上)和Windows Task Manager来检查每次停止时的内存使用情况。但是valgrind不会报告任何内存泄漏。

PS:请不要问为什么我使用共享指针。提出不同的方法将很有用,但此问题的主要目的是理解这种行为。因为即使cppref也无法解释这一点。欣赏是否有人可以解释这种行为而不是解决它。

我不需要修复。我需要一个解释。

塞尔比

我使用了Linux top(在WSL上)和Windows Task Manager来检查每次停止时的内存使用情况。但是valgrind不会报告任何内存泄漏。

TLDR:相对于其他代码路径,分配内存是一项昂贵的操作。为了提高性能,几乎所有堆管理器都将继续保留内存以进行后续分配,而不是直接将其返回给它。

当您的程序代码分配内存时,它会通过一层内存堆来授予该分配。当您的程序调用“ new”(通过make_shared)时,它将调用C / C ++运行时来分配内存。C / C ++运行时,如果堆中没有足够大的连续字节范围来分配该分配,它将通过OS特定的库调用将其缩减为进程堆,以请求更多的内存。如果进程堆没有足够的资源立即分配,它会进行系统调用以分配更多的虚拟内存...以及可能还会有更多的堆。而且,别忘了可能必须调入内存,但是我离题了。

这些堆访问中的每一个都需要锁定数据结构以管理请求的堆分配,并且可能需要对OS进行系统调用。可能需要付出额外的努力才能根据需要折叠或重新排列内存块。这就是为什么内存堆是分层的。如果每个新调用和删除调用都直接发送给虚拟内存管理器,则程序和系统的性能将因大量的系统调用而确实变慢。

类似地,将内存释放回原来的位置也会带来类似的性能损失。这些堆可能会在想要压缩时释放回其父堆,但不要指望它会通过单次调用“删除”来做到这一点。

诸如Top和Task Manager之类的工具只能从OS观察进程分配的虚拟内存量。他们不知道程序的运行时库正在管理免费分配。而Valgrind会将自己插入代码中,并且可以将自身挂钩到C ++内存管理器。但是,甚至Valgrind也会不时报告错误肯定。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

std set of boost :: shared_ptr <string>

来自分类Dev

QVariant与std :: shared_ptr

来自分类Dev

QVariant与std :: shared_ptr

来自分类Dev

std :: shared_ptr预分配内存

来自分类Dev

使用std :: move与std :: shared_ptr

来自分类Dev

使用boost :: shared_ptr <std :: list <T >>初始化boost :: shared_ptr <std :: vector <T >>

来自分类Dev

std :: unordered_map插入错误shared_ptr C ++

来自分类Dev

C ++使用指向std :: shared_ptr的Raw指针

来自分类Dev

std :: unordered_map插入错误shared_ptr C ++

来自分类Dev

C ++ std :: shared_ptr参考的reinterpret_cast优化

来自分类Dev

C++ 中 std::shared_ptr 数组的工作原理

来自分类Dev

使用C ++ std :: unique_ptr <>或std :: shared_ptr <>来管理Objective-C对象

来自分类Dev

使用C ++ std :: unique_ptr <>或std :: shared_ptr <>来管理Objective-C对象

来自分类常见问题

在C ++中,空std :: shared_ptr和空std :: shared_ptr有什么区别?

来自分类Dev

如何将std :: vector <boost :: shared_ptr <T >>复制到std :: list <T>

来自分类Dev

拥有std :: make_shared的std :: shared_ptr

来自分类Dev

std :: shared_ptr和继承

来自分类Dev

std :: shared_ptr深层复制对象

来自分类Dev

std :: function和shared_ptr

来自分类Dev

使用* this作为std :: shared_ptr

来自分类Dev

数据与memcpy的std :: shared_ptr分配

来自分类Dev

可重用的std :: shared_ptr

来自分类Dev

std :: shared_ptr深层复制对象

来自分类Dev

数据与memcpy的std :: shared_ptr分配

来自分类Dev

使用* this作为std :: shared_ptr

来自分类Dev

std :: shared_ptr初始化

来自分类Dev

如何访问std :: shared_ptr的内容?

来自分类Dev

std :: shared_ptr删除者类型

来自分类Dev

移动 std::shared_ptr 的函数声明