gpt4 book ai didi

c++ - 为什么进程的 "Private Bytes"内存计数器永远不会返回到它的原始值?

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:05:54 26 4
gpt4 key购买 nike

如果我有一个 native C++ 程序并查看它的初始“私有(private)字节”内存计数器,为什么在创建然后删除对象后它不会恢复到原始值?

例如,如果我有一个有两个按钮的应用程序(32 位, native C++ MFC)。一个循环分配一个对象的 1,000,000 个实例,然后另一个按钮删除这些相同的对象。

如果我查看进程的专用字节计数器,我有以下 3 个值:
.
说明…………私有(private)字节数
===================================
应用程序启动.......................1,608K
对象。创建.......33,176K
对象。已删除.........2,520K

912K ( 2520-1608 ) 泄漏 ?

假设我的代码没有泄漏内存,但我相信这不是为什么私有(private)字节数不会回到EXACT初始值?

如果我再次点击这两个按钮(没有重新启动程序)(第一个按钮创建另外 1,000,000 个对象)并且第二个按钮删除它们我有这个:

对象。创建.......33,472K
对象。已删除.........2,552K

( 2552-2520 ) 的新泄漏 = 32K

我只是在寻找关于为什么内存不会恢复到原始值的解释。

示例代码(一些生成的代码被剥离以减少噪音):

class Person
{
public:
Person(void);
~Person(void);

Person* Next;
int A;
int B;
int C;
int D;

};


class Cdelme_MFC2005_MemoryTestDlg : public CDialog
{
// some code stripped out here to simplify reading.

Person* m_PeopleList_First;
Person* m_PeopleList_Last;

public:
afx_msg void OnBnClickedButtonAllocate();
afx_msg void OnBnClickedButtonFree();
};


Cdelme_MFC2005_MemoryTestDlg::Cdelme_MFC2005_MemoryTestDlg(CWnd* pParent /*=NULL*/)
: CDialog(Cdelme_MFC2005_MemoryTestDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

m_PeopleList_First = NULL;
m_PeopleList_Last = NULL;

}


void Cdelme_MFC2005_MemoryTestDlg::OnBnClickedButtonAllocate()
{
if ( m_PeopleList_First == NULL )
{
m_PeopleList_First = new Person();
m_PeopleList_First->A = 0;
m_PeopleList_Last = m_PeopleList_First;
}

int MAX = 1000000;
for (int i = 0; i <MAX ; i++)
{
Person* p = new Person();
p->A = i;
m_PeopleList_Last->Next = p;
m_PeopleList_Last = p;
}
}

void Cdelme_MFC2005_MemoryTestDlg::OnBnClickedButtonFree()
{
Person* p = m_PeopleList_First;
while ( p != NULL )
{
Person* pNext = p->Next;
delete p;
p = pNext;
}
m_PeopleList_First = NULL;
m_PeopleList_Last = NULL;
}

最佳答案

这里有几个问题。首先,当您删除 内存时,标准库通常不会将该内存释放回操作系统。它通常保留该内存的所有权,但将其标记为可用于其他分配。由于您显然使用的是 MS VC++,因此您可以在执行 delete 后使用 _heapwalk 来查看仍在进程堆中的空闲 block 。如果您真的想要,您也可以调用 _heapmin 将(至少大部分)空闲内存释放回操作系统。回到过去(MS VC++ 4.0,如果有内存的话)MS 有一个版本的标准库直接使用操作系统的内存管理,但性能很差(说得好听点),所以并没有持续很长时间。

其次,MFC 在后台进行了大量工作,它分配各种“东西”以使事情正常进行,但不会在之后立即释放它们(并且由于其中大部分或多或少是不可见的,因此并不容易/直接释放它的方式)。

关于c++ - 为什么进程的 "Private Bytes"内存计数器永远不会返回到它的原始值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3916514/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com