map的内存分配机制分析

该程序演示了map在形成的时候对内存的操作和分配。

因为自己对平衡二叉树的创建细节理解不够,还不太明白程序所显示的日志。等我明白了,再来修改这个文档。

/*
功能说明:
    map的内存分配机制分析。
代码说明:
    map所管理的内存地址可以是不连续的。如果key是可以通过<排序的,那么,map最后的结果是有序的。它是通过一个平衡二叉树来保存数据。所以,其查找效率极高。
实现方式:

限制条件或者存在的问题:
    无
*/
#include <iostream>
#include <string>
#include <map>

#include <windows.h>

using namespace std;

class CData
{
public:
    CData()
    {
        sequence = 0;
        this->remark = "default string";

        cout << "CData()\t" << toString() << "\t" << this << endl;
    }

    CData(int i, string &s)
    {
        this->sequence = i;
        this->remark = s;

        cout << "CData(int i,string &s)\t" << toString() << "\t" << this << endl;
    }

    CData(const CData &data)
    {
        this->sequence = data.sequence;
        this->remark = data.remark;

        cout << "CData(const CData &data)\t" << toString() << "\t" << this << endl;
    }

    CData operator = (const CData &data)
    {
        this->sequence = data.sequence;
        this->remark = data.remark;

        cout << "CData operator = (const CData &data)\t" << toString() << "\t" << this << endl;

        return *this;
    }

    void setSequence(const int i)
    {
        this->sequence = i;
    }

    void setRemark(const string &s)
    {
        this->remark = s;
    }

    string toString() const
    {
        char tmp[2048] = { 0 };
        sprintf(tmp, "[sequence:%d | remark:%s]", this->sequence, this->remark.c_str());

        //此处应该有内存复制操作,所以不用担心返回后tmp数组所指向的内存被修改或者不存在的情况。
        return tmp;
    }

    ~CData()
    {
        cout << "~CData()\t" << this << endl;
    }
protected:
private:
    int sequence;
    string remark;
};

int main(int argc, char **argv)
{
    cout << "process begin at " << (void*)&main << endl;

    string str = "baby_test";
    CData data1(1, str);
    CData data2(2, str);
    CData data3(3, str);
    CData data4(4, str);
    CData data5(5, str);
    CData data6(6, str);
    CData data7(7, str);
    CData data8(8, str);
    CData data9(9, str);
    CData data10(10, str);

    cout << "push CData to map" << endl;
    map<int,CData> map_data;
    cout << "max size of list<CData> is " << map_data.max_size() << endl;
    cout << "size of list<CData> is " << map_data.size() << endl;

    cout << "****************map_data.push_back(data1)" << endl;
    map_data.insert(make_pair(1, data1));
    Sleep(2 * map_data.size());

    cout << "****************map_data.push_back(data2)" << endl;
    map_data.insert(make_pair(2, data2));
    Sleep(2 * map_data.size());

    cout << "****************map_data.push_back(data3)" << endl;
    map_data.insert(make_pair(3, data3));
    Sleep(2 * map_data.size());

    cout << "****************map_data.push_back(data4)" << endl;
    map_data.insert(make_pair(4, data4));
    Sleep(2 * map_data.size());

    cout << "****************map_data.push_back(data5)" << endl;
    map_data.insert(make_pair(5, data5));
    Sleep(2 * map_data.size());

    cout << "****************map_data.push_back(data6)" << endl;
    map_data.insert(make_pair(6, data6));
    Sleep(2 * map_data.size());

    cout << "****************map_data.push_back(data7)" << endl;
    map_data.insert(make_pair(7, data7));
    Sleep(2 * map_data.size());

    cout << "****************map_data.push_back(data8)" << endl;
    map_data.insert(make_pair(8, data8));
    Sleep(2 * map_data.size());

    cout << "****************map_data.push_back(data9)" << endl;
    map_data.insert(make_pair(9, data9));
    Sleep(2 * map_data.size());

    cout << "****************map_data.push_back(data10)" << endl;
    map_data.insert(make_pair(10, data10));
    Sleep(2 * map_data.size());

    // 程序到此为止,可以看到在每次push的时候,对象的复制构造函数会调用2次。为什么是2次?
    cout << "===============show map by iterator" << endl;
    for (map<int,CData>::iterator itr = map_data.begin(); itr != map_data.end(); itr++)
    {
        // 显示的地址信息,是每次push的时候所复制的对象的地址。
        cout<<"key:"<< itr->first<<"\t" << "value:address of itr is " << &(itr->second) << " and msg is " << itr->second.toString() << endl;
    }

    cout << "===============clear map 1" << endl;
    // map中的元素不是指针,此处的清理,会调用析构函数。
    map_data.clear();

    cout << "****************map_data.push_back(data6)" << endl;
    map_data.insert(make_pair(6, data6));
    Sleep(2 * map_data.size());

    cout << "****************map_data.push_back(data2)" << endl;
    map_data.insert(make_pair(2, data2));
    Sleep(2 * map_data.size());

    cout << "****************map_data.push_back(data3)" << endl;
    map_data.insert(make_pair(3, data3));
    Sleep(2 * map_data.size());

    cout << "****************map_data.push_back(data1" << endl;
    map_data.insert(make_pair(1, data1));
    Sleep(2 * map_data.size());

    cout << "****************map_data.push_back(data10)" << endl;
    map_data.insert(make_pair(10, data10));
    Sleep(2 * map_data.size());

    cout << "****************map_data.push_back(data4)" << endl;
    map_data.insert(make_pair(4, data4));
    Sleep(2 * map_data.size());

    cout << "****************map_data.push_back(data7)" << endl;
    map_data.insert(make_pair(7, data7));
    Sleep(2 * map_data.size());

    cout << "****************map_data.push_back(data8)" << endl;
    map_data.insert(make_pair(8, data8));
    Sleep(2 * map_data.size());

    cout << "****************map_data.push_back(data9)" << endl;
    map_data.insert(make_pair(9, data9));
    Sleep(2 * map_data.size());

    cout << "****************map_data.push_back(data5)" << endl;
    map_data.insert(make_pair(5, data5));
    Sleep(2 * map_data.size());

    // 程序到此为止,可以看到在每次push的时候,对象的复制构造函数会调用2次。为什么是2次?
    cout << "===============show map by iterator 2" << endl;
    for (map<int, CData>::iterator itr = map_data.begin(); itr != map_data.end(); itr++)
    {
        // 显示的地址信息,是每次push的时候所复制的对象的地址。
        // 可以看到,不管插入的数据是如何的乱序,map的结果是排好序的。
        cout << "key:" << itr->first << "\t" << "value:address of itr is " << &(itr->second) << " and msg is " << itr->second.toString() << endl;
    }

    cout << "===============clear map 2" << endl;
    // map中的元素不是指针,此处的清理,会调用析构函数。
    map_data.clear();

    cout << "======================end of process" << endl;

    return 0;
}

程序的输出结果:
process begin at 00C917FD
CData(int i,string &s)  [sequence:1 | remark:baby_test] 0053F6F0
CData(int i,string &s)  [sequence:2 | remark:baby_test] 0053F6C8
CData(int i,string &s)  [sequence:3 | remark:baby_test] 0053F6A0
CData(int i,string &s)  [sequence:4 | remark:baby_test] 0053F678
CData(int i,string &s)  [sequence:5 | remark:baby_test] 0053F650
CData(int i,string &s)  [sequence:6 | remark:baby_test] 0053F628
CData(int i,string &s)  [sequence:7 | remark:baby_test] 0053F600
CData(int i,string &s)  [sequence:8 | remark:baby_test] 0053F5D8
CData(int i,string &s)  [sequence:9 | remark:baby_test] 0053F5B0
CData(int i,string &s)  [sequence:10 | remark:baby_test]        0053F588
push CData to map
max size of list<CData> is 82595524
size of list<CData> is 0
****************map_data.push_back(data1)
CData(const CData &data)        [sequence:1 | remark:baby_test] 0053F158
CData(const CData &data)        [sequence:1 | remark:baby_test] 005F6F74
~CData()        0053F158
****************map_data.push_back(data2)
CData(const CData &data)        [sequence:2 | remark:baby_test] 0053F108
CData(const CData &data)        [sequence:2 | remark:baby_test] 005FE2A4
~CData()        0053F108
****************map_data.push_back(data3)
CData(const CData &data)        [sequence:3 | remark:baby_test] 0053F0B8
CData(const CData &data)        [sequence:3 | remark:baby_test] 005FE304
~CData()        0053F0B8
****************map_data.push_back(data4)
CData(const CData &data)        [sequence:4 | remark:baby_test] 0053F068
CData(const CData &data)        [sequence:4 | remark:baby_test] 005FE364
~CData()        0053F068
****************map_data.push_back(data5)
CData(const CData &data)        [sequence:5 | remark:baby_test] 0053F018
CData(const CData &data)        [sequence:5 | remark:baby_test] 005FE3C4
~CData()        0053F018
****************map_data.push_back(data6)
CData(const CData &data)        [sequence:6 | remark:baby_test] 0053EFC8
CData(const CData &data)        [sequence:6 | remark:baby_test] 005FE424
~CData()        0053EFC8
****************map_data.push_back(data7)
CData(const CData &data)        [sequence:7 | remark:baby_test] 0053EF78
CData(const CData &data)        [sequence:7 | remark:baby_test] 005FE484
~CData()        0053EF78
****************map_data.push_back(data8)
CData(const CData &data)        [sequence:8 | remark:baby_test] 0053EF28
CData(const CData &data)        [sequence:8 | remark:baby_test] 005FE4E4
~CData()        0053EF28
****************map_data.push_back(data9)
CData(const CData &data)        [sequence:9 | remark:baby_test] 0053EED8
CData(const CData &data)        [sequence:9 | remark:baby_test] 005FED9C
~CData()        0053EED8
****************map_data.push_back(data10)
CData(const CData &data)        [sequence:10 | remark:baby_test]        0053EE88
CData(const CData &data)        [sequence:10 | remark:baby_test]        005FEDFC
~CData()        0053EE88
===============show map by iterator
key:1   value:address of itr is 005F6F74 and msg is [sequence:1 | remark:baby_test]
key:2   value:address of itr is 005FE2A4 and msg is [sequence:2 | remark:baby_test]
key:3   value:address of itr is 005FE304 and msg is [sequence:3 | remark:baby_test]
key:4   value:address of itr is 005FE364 and msg is [sequence:4 | remark:baby_test]
key:5   value:address of itr is 005FE3C4 and msg is [sequence:5 | remark:baby_test]
key:6   value:address of itr is 005FE424 and msg is [sequence:6 | remark:baby_test]
key:7   value:address of itr is 005FE484 and msg is [sequence:7 | remark:baby_test]
key:8   value:address of itr is 005FE4E4 and msg is [sequence:8 | remark:baby_test]
key:9   value:address of itr is 005FED9C and msg is [sequence:9 | remark:baby_test]
key:10  value:address of itr is 005FEDFC and msg is [sequence:10 | remark:baby_test]
===============clear map 1
~CData()        005FEDFC
~CData()        005FED9C
~CData()        005FE4E4
~CData()        005FE484
~CData()        005FE424
~CData()        005FE3C4
~CData()        005FE364
~CData()        005FE304
~CData()        005FE2A4
~CData()        005F6F74
****************map_data.push_back(data6)
CData(const CData &data)        [sequence:6 | remark:baby_test] 0053EDE0
CData(const CData &data)        [sequence:6 | remark:baby_test] 005F6F74
~CData()        0053EDE0
****************map_data.push_back(data2)
CData(const CData &data)        [sequence:2 | remark:baby_test] 0053ED90
CData(const CData &data)        [sequence:2 | remark:baby_test] 005FED9C
~CData()        0053ED90
****************map_data.push_back(data3)
CData(const CData &data)        [sequence:3 | remark:baby_test] 0053ED40
CData(const CData &data)        [sequence:3 | remark:baby_test] 005FEDFC
~CData()        0053ED40
****************map_data.push_back(data1
CData(const CData &data)        [sequence:1 | remark:baby_test] 0053ECF0
CData(const CData &data)        [sequence:1 | remark:baby_test] 005FEE5C
~CData()        0053ECF0
****************map_data.push_back(data10)
CData(const CData &data)        [sequence:10 | remark:baby_test]        0053ECA0
CData(const CData &data)        [sequence:10 | remark:baby_test]        005FEEBC
~CData()        0053ECA0
****************map_data.push_back(data4)
CData(const CData &data)        [sequence:4 | remark:baby_test] 0053EC50
CData(const CData &data)        [sequence:4 | remark:baby_test] 005FEF1C
~CData()        0053EC50
****************map_data.push_back(data7)
CData(const CData &data)        [sequence:7 | remark:baby_test] 0053EC00
CData(const CData &data)        [sequence:7 | remark:baby_test] 005FEF7C
~CData()        0053EC00
****************map_data.push_back(data8)
CData(const CData &data)        [sequence:8 | remark:baby_test] 0053EBB0
CData(const CData &data)        [sequence:8 | remark:baby_test] 005FE2A4
~CData()        0053EBB0
****************map_data.push_back(data9)
CData(const CData &data)        [sequence:9 | remark:baby_test] 0053EB60
CData(const CData &data)        [sequence:9 | remark:baby_test] 005FE304
~CData()        0053EB60
****************map_data.push_back(data5)
CData(const CData &data)        [sequence:5 | remark:baby_test] 0053EB10
CData(const CData &data)        [sequence:5 | remark:baby_test] 005FE364
~CData()        0053EB10
===============show map by iterator 2
key:1   value:address of itr is 005FEE5C and msg is [sequence:1 | remark:baby_test]
key:2   value:address of itr is 005FED9C and msg is [sequence:2 | remark:baby_test]
key:3   value:address of itr is 005FEDFC and msg is [sequence:3 | remark:baby_test]
key:4   value:address of itr is 005FEF1C and msg is [sequence:4 | remark:baby_test]
key:5   value:address of itr is 005FE364 and msg is [sequence:5 | remark:baby_test]
key:6   value:address of itr is 005F6F74 and msg is [sequence:6 | remark:baby_test]
key:7   value:address of itr is 005FEF7C and msg is [sequence:7 | remark:baby_test]
key:8   value:address of itr is 005FE2A4 and msg is [sequence:8 | remark:baby_test]
key:9   value:address of itr is 005FE304 and msg is [sequence:9 | remark:baby_test]
key:10  value:address of itr is 005FEEBC and msg is [sequence:10 | remark:baby_test]
===============clear map 2
~CData()        005FEEBC
~CData()        005FE304
~CData()        005FE2A4
~CData()        005FEF7C
~CData()        005F6F74
~CData()        005FE364
~CData()        005FEF1C
~CData()        005FEDFC
~CData()        005FED9C
~CData()        005FEE5C
======================end of process
~CData()        0053F588
~CData()        0053F5B0
~CData()        0053F5D8
~CData()        0053F600
~CData()        0053F628
~CData()        0053F650
~CData()        0053F678
~CData()        0053F6A0
~CData()        0053F6C8
~CData()        0053F6F0

时间: 2024-08-07 08:37:54

map的内存分配机制分析的相关文章

list的内存分配机制分析

该程序演示了list在内存分配时候的问题.里面的备注信息是我的想法. /* 功能说明: list的内存分配机制分析. 代码说明: list所管理的内存地址可以是不连续的.程序在不断的push_back的过程中,程序仅会将操作的元素进行复制一份,保存到list中.通过复制构造函数和析构函数,可以看到这些操作. 实现方式: 限制条件或者存在的问题: 无 */ #include <iostream> #include <string> #include <list> #inc

vector的内存分配机制分析

该程序初步演示了我对vector在分配内存的时候的理解.可能有误差,随着理解的改变,改代码可以被修改. 1 /* 2 功能说明: 3 vector的内存分配机制分析. 4 代码说明: 5 vector所管理的内存地址是连续的.程序在不断的push_back的过程中,如果当前所管理的内存不能装下新的元素的时候,程序会创建更大的地址连续的空间来保存更多的元素. 6 这种机制会引起大量的无用的复制和删除操作.如果vector的元素为类结构的时候,他就会有很多临时变量产生.通过复制构造函数和析构函数,可

Go语言内存分配机制

前言: 本文是学习<<go语言程序设计>> -- 清华大学出版社(王鹏 编著) 的2014年1月第一版 做的一些笔记 , 如有侵权, 请告知笔者, 将在24小时内删除, 转载请注明出处! Go语言有两种内存分配机制 , 分别是内置函数 new() 和make(). - new() - 定义: func new(Type) * Type - 返回值是一个内存块指针 - new() 是一个内置函数, 不同于其他语言中的new操作符, 它只将内存清零, 而不是初始化内存. - make(

memcached学习——memcached的内存分配机制Slab Allocation、内存使用机制LRU、常用监控记录(四)

内存分配机制Slab Allocation 本文参考博客:https://my.oschina.net/bieber/blog/505458 Memcached的内存分配是以slabs为单位的,会根据初始chunk大小.增长因子.存储数据的大小实际划分出多个不同的slabs class,slab class中包含若干个等大小的trunk和一个固定48byte的item信息.trunk是按页存储的,每一页成为一个page(默认1M). 1.slabs.slab class.page三者关系: sl

JVM虚拟机-03、JVM内存分配机制与垃圾回收算法

JVM虚拟机-03.JVM内存分配机制与垃圾回收算法 1 JVM内存分配与回收 1.1 对象优先在Eden区分配 大多数情况下,对象在新生代中?Eden?区分配.当?Eden?区没有足够空间进行分配时,虚拟机将发起一次Minor?GC.我们来进行实际测试一下.在测试之前我们先来看看?Minor?GC和Full?GC?有什么不同呢? Minor?GC/Young?GC:指发生新生代的的垃圾收集动作,MinorGC非常频繁,回收速度一般也比较快. Major?GC/Full?GC:一般会回收老年代,

java内存分配机制

java内存分配机制 通过这几天对一个内存溢出程序的监控,学习了程序运行时对内存的使用机制,在这里和大家分享下. Java程序运行在JVM(Java  Virtual Machine,Java虚拟机)上,可以把JVM理解成Java程序和操作系统之间的桥梁,JVM实现了Java的平台无关性,由此可见JVM的重要性.所以在学习Java内存分配原理的时候一定要牢记这一切都是在JVM中进行的,JVM是内存分配原理的基础与前提.         一个完整的Java程序运行过程会涉及以下内存区域: 寄存器:

Memcache简介 &amp; 内存分配机制

关于这个东西里面到底应该存放数据网上一直有很多种说法,有的说sql进行md5之后作为键值,结果作为内容存放,也有人说按照业务逻辑错放,反正是炒的不亦乐乎. 本人经过将近2年的实践,最后还是觉得要根据业务逻辑来存放,不能将sql加密然后对应结果集存放.这样做,基本上无法实现数据的及时更新,只能依靠memcahce的过期时间来更新.资讯类的静态数据比较合适,不过这种网站一般会做静态化的处理,所以memcache也发挥不了太大用途.真正有用武之地的地方是社区类网站,这类网站大部分是动态数据,而且性能要

[C++]内存管理器--谈论如何自定义内存分配机制

内存管理器–谈论如何自定义内存分配机制 Memory pools, also called fixed-size blocks allocation, is the use of pools for memory management that allows dynamic memory allocation comparable to malloc or C++'s operator new. As those implementations suffer from fragmentation

Java中的内存分配机制

Java的内存分为两种:一种是栈内存,一种是堆内存. 在函数中定义的一些基本类型变量和对象的引用都在函数的栈内存中分配.当在一个代码块中定义一个变量的时候,java就在栈中为其分配内存,当超过作用域的时候内存自动释放. 对内存用来存放new创建的对象和数组.在堆中分配的内存,由java虚拟机的垃圾回收机器管理.java的堆是运行时数据区,堆的优势是可以动态的分配内存大小,生存周期也不必事先告诉编译器,但是,由于是动态分配,存取速度慢. 栈的优势是比堆的存取速度快,仅次于寄存器,栈数据可以共享,但