使用valgrind查看xerces-c++内存使用情况

本文通过使用valgrind工具,统计并分析了Xerces创建大量DOM节点时的内存消耗情况,揭示了主要内存占用来自DOMElementImpl、DOMTextImpl等对象的创建。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文结构

上一篇说到xerces会耗费大量内存,今天我们用工具valgrind统计下各个函数申请堆内存的比例。我会先写一小段demo,它会创建很多节点; 然后使用valgrind massif查看heap profiler.

1) demo

本demo会创建大约5000个Product节点,每个Product有70个子节点Item(你可以试着把字符串改成全都不一样的,结果会不一样), 如下

 <Company>
          <Product1>
            <Item>MEMORY TEST 1</Item>
            <Item>MEMORY TEST 1</Item>
            <Item>MEMORY TEST 1</Item>
            <Item>MEMORY TEST 1</Item>
            <Item>MEMORY TEST 1</Item>
            <Item>MEMORY TEST 1</Item>
            <Item>MEMORY TEST 1</Item>
          </Product1>

          <Product2>
            <Item>MEMORY TEST 2</Item>
            <Item>MEMORY TEST 2</Item>
            <Item>MEMORY TEST 2</Item>
            <Item>MEMORY TEST 2</Item>
            <Item>MEMORY TEST 2</Item>
            <Item>MEMORY TEST 2</Item>
            <Item>MEMORY TEST 2</Item>
          </Product2>
        </Company>

主要代码如下,外围代码请参考xerces下的samples/createDOMDocument.cpp

DOMDocument* doc = impl->createDocument(
				   0,                    // root element namespace URI.
				   X("Company"),         // root element name
				   0);                   // document type object (DTD).

DOMElement* rootElem = doc->getDocumentElement();

for(int i=1; i<=5000; i++){
	DOMElement*  prodElem = doc->createElement(X((std::string("Product")+std::to_string(i)).c_str()));
	for(int j=1; j<70; j++){
		DOMElement*  itemElem = doc->createElement(X("Item"));
		DOMText*    itemDataVal = doc->createTextNode(X((std::string("MEMORY TEST ")+std::to_string(i)).c_str()));
		itemElem->appendChild(itemDataVal);
		prodElem->appendChild(itemElem);
   }
   rootElem->appendChild(prodElem);
}

2) heap profiler结果

$ valgrind --tool=massif ./a.out
$ ms_print massif.out.*

99.97% (111,454,411B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
->99.90% (111,378,444B) 0x4FF6168: xercesc_3_1::MemoryManagerImpl::allocate(unsigned long) (MemoryManagerImpl.cpp:40)
| ->99.68% (111,132,672B) 0x4F9EB13: xercesc_3_1::DOMDocumentImpl::allocate(unsigned long) (DOMDocumentImpl.cpp:884)
| | ->48.92% (54,542,336B) 0x4FA2A36: xercesc_3_1::DOMDocumentImpl::allocate(unsigned long, xercesc_3_1::DOMMemoryManager::NodeObjectType) (DOMDocumentImpl.cpp:1502)
| | | ->33.39% (37,224,448B) 0x4FA0F1A: operator new (DOMDocumentImpl.hpp:454)
| | | | ->33.39% (37,224,448B) 0x4FA0F1A: xercesc_3_1::DOMDocumentImpl::createElement(unsigned short const*) (DOMDocumentImpl.cpp:342)
| | | |   ->32.92% (36,700,160B) 0x4024D3: main (xercesMemoryTest.cpp:175)
| | | |   |
| | | |   ->00.47% (524,288B) in 1+ places, all below ms_print's threshold (01.00%)
| | | |
| | | ->15.52% (17,301,504B) 0x4F9EFE9: operator new (DOMDocumentImpl.hpp:454)
| | | | ->15.52% (17,301,504B) 0x4F9EFE9: xercesc_3_1::DOMDocumentImpl::createTextNode(unsigned short const*) (DOMDocumentImpl.cpp:407)
| | | |   ->15.52% (17,301,504B) 0x402594: main (xercesMemoryTest.cpp:176)
| | | |
| | | ->00.01% (16,384B) in 1+ places, all below ms_print's threshold (01.00%)
| | |
| | ->17.63% (19,660,800B) 0x4FAA424: operator new (DOMDocumentImpl.hpp:469)
| | | ->17.63% (19,660,800B) 0x4FAA424: xercesc_3_1::DOMElementImpl::DOMElementImpl(xercesc_3_1::DOMDocument*, unsigned short const*) (DOMElementImpl.cpp:53)
| | |   ->17.63% (19,660,800B) 0x4FA0F2E: xercesc_3_1::DOMDocumentImpl::createElement(unsigned short const*) (DOMDocumentImpl.cpp:342)
| | |     ->17.63% (19,660,800B) 0x4024D3: main (xercesMemoryTest.cpp:175)
| | |
| | ->17.08% (19,038,208B) 0x4F9B7FE: operator new (DOMDocumentImpl.hpp:469)
| | | ->17.08% (19,038,208B) 0x4F9B7FE: xercesc_3_1::DOMCharacterDataImpl::DOMCharacterDataImpl(xercesc_3_1::DOMDocument*, unsigned short const*) (DOMCharacterDataImpl.cpp:40)
| | |   ->17.08% (19,038,208B) 0x4FBF1E2: xercesc_3_1::DOMTextImpl::DOMTextImpl(xercesc_3_1::DOMDocument*, unsigned short const*) (DOMTextImpl.cpp:47)
| | |     ->17.08% (19,038,208B) 0x4F9EFFB: xercesc_3_1::DOMDocumentImpl::createTextNode(unsigned short const*) (DOMDocumentImpl.cpp:407)
| | |       ->17.08% (19,038,208B) 0x402594: main (xercesMemoryTest.cpp:176)
| | |
| | ->15.58% (17,367,040B) 0x4FBE238: xercesc_3_1::DOMBuffer::DOMBuffer(xercesc_3_1::DOMDocumentImpl*, unsigned long) (DOMStringPool.cpp:38)
| | | ->15.58% (17,367,040B) 0x4F9B812: xercesc_3_1::DOMCharacterDataImpl::DOMCharacterDataImpl(xercesc_3_1::DOMDocument*, unsigned short const*) (DOMCharacterDataImpl.cpp:40)
| | |   ->15.58% (17,367,040B) 0x4FBF1E2: xercesc_3_1::DOMTextImpl::DOMTextImpl(xercesc_3_1::DOMDocument*, unsigned short const*) (DOMTextImpl.cpp:47)
| | |     ->15.58% (17,367,040B) 0x4F9EFFB: xercesc_3_1::DOMDocumentImpl::createTextNode(unsigned short const*) (DOMDocumentImpl.cpp:407)
| | |       ->15.58% (17,367,040B) 0x402594: main (xercesMemoryTest.cpp:176)
| | |
| | ->00.47% (524,288B) in 1+ places, all below ms_print's threshold (01.00%)
| |
| ->00.22% (245,772B) in 1+ places, all below ms_print's threshold (01.00%)
|
->00.07% (75,967B) in 1+ places, all below ms_print's threshold (01.00%)

一共大约耗费了111M的堆内存(而如果转成字符串也就10M左右),主要耗费内存的地方:

  1. 33.39% (37,224,448B) 创建DOMElementImpl(350000个Node)。
  2. 15.52% (17,301,504B) 创建DOMTextImpl (350000个)
  3. 17.63% (19,660,800B) 创建DOMAttrMapImpl
  4. 17.08% (19,038,208B) 创建DOMBuffer
  5. 15.58% (17,367,040B) 创建DOMBuffer下的capacity
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

深山老宅

鸡蛋不错的话,要不要激励下母鸡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值