如何确定内存中COM对象的大小

How to determine COM object size in memory?

本文关键字:对象 COM 何确定 内存      更新时间:2023-10-16

我有MSXML2::IXMLDOMNodeList接口。我可以使用以下代码从该列表中找到所有MSXML2::IXMLDOMNode-s的公共长度:

MSXML2::IXMLDOMNode* pDOMXMLNode = 0;
BSTR NodeText;
ULONG lValueSize = 0;
ULONG lCommonLength = 0;
while(pDOMXmlNodeList->nextNode(&pDOMXMLNode)== S_OK)
{      
 pDOMXMLNode->get_xml(&NodeText);      
 CString strNode(NodeText);
 lValueSize += strNode.GetLength();      
}    
lCommonLength += lValueSize;

这很好,但这不是我想找到的:我想确定对象实例在内存中的大小。有没有一种方法可以在C++中实现它?

COM没有提供一种了解对象大小的方法。在某种程度上,它不能——如果对象在另一个进程中,你想知道进程中存根的大小还是其他进程中实际对象的大小?

您可以通过创建大量实例并使用内存监控来了解这是如何改变整个应用程序内存占用的。

您想要的是实例大小,还是对象的总内存占用?理解这种区别非常重要。

如果实例包含一个指向动态内存的指针,那么只有4到8个字节的实例数据,但指向的内存块可能和任何东西一样大。正如其他人所说,也没有可靠的方法来知道。实例大小可能会混淆我的封送处理。内存foorprint可能会被私有堆、内存共享等混淆。

COM本身没有为此提供任何机制。C++也没有——你所说的COM服务器甚至可能不是用C++编写的(尽管在MSXML的情况下,可能是这样)。

对于MSXML库的特定版本和构建,Microsoft符号服务器可以提供对实现细节的一些见解;例如,它可能会为您提供实例大小。然而,这并不能扩展到生产——你真的想提供一个自制的调试器来下载MSXML的符号并在用户的机器上解析它们吗?

至于内存占用,那么进程内存消耗快照就是你的朋友,即使是那些快照也应该像盐一样大。

我不确定您是否可以确定COM对象的确切大小。但是,您可以使用以下技巧来确定COM对象的大致大小。

//First determine how much memory your program is currently using. 
//Say it is currently `m1`
//allocate COM object
//Now again, determine how much memory your program is using
//Say it is m2
//COM object size = m2 - m1

Microsoft提供了一些API来确定程序的内存状态。以下是您如何将上述技术应用于Microsoft API:

_CrtMemState m1;
_CrtMemCheckpoint( &m1 );
 //COM object creation
_CrtMemState m2;
_CrtMemCheckpoint( &m2 );
_CrtMemState difference;
_CrtMemDifference(&difference, &m1,&m2);

对象difference告诉COM对象的大小。您可以将其值打印为:

_CrtMemDumpStatistics( &difference );

或者,您可以进一步分析对象difference,其类型为_CrtMemState,定义为:

//crtdbg.h
struct _CrtMemBlockHeader;
typedef struct _CrtMemState
{
    struct _CrtMemBlockHeader * pBlockHeader;
    size_t lCounts[_MAX_BLOCKS];
    size_t lSizes[_MAX_BLOCKS];
    size_t lHighWaterCount;
    size_t lTotalCount;
} _CrtMemState;

阅读MSDN上的文档:

  • 内存状态比较