C++基本组件之内存池详解

内存池概念

1:尽量减少malloc的次数

2:频繁申请小块内存空间都造成空间的极大浪费

3:利用new和delete运算符重载,替代系统调用

4:减少malloc的次数,可在一定程度上提高效率

5:用malloc申请一个大块内存,从一大块内存中,一点点分配给用户

6:当一大块快用光了,再申请一大块

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

#include <iostream>

#include <malloc.h>

#include <time.h>

using namespace std;

namespace _nm1

{

    //内存池

    //减少malloc的次数,减少对内存的浪费

    //尤其是频繁地申请小块内存

    //速度和效率的提升并不是特别明显,因为malloc的速度也不慢

    //用malloc申请

    //一个大块内存,从一大块内存中,一点点分配给用户

    //当一大块快用光了,再申请一大块

    class A

    {

    public:

        static void *operator new(size_t size);

        //静态成员函数,属于类,不属于对象

        static void operator delete(void *phead);

        static int m_iCout;//分配计数统计

        static int m_iMallocCount;//malloc次数统计

    private:

        A *next;//指针域,指向下一个空间

        static A* m_FreePosi;//总是指向一块分配出去的内存首地址

        static int m_sTrunkCout;//一次分配多少倍

    };

    int A::m_iCout = 0;//初始化

    int A::m_iMallocCount = 0;

    A *A::m_FreePosi = nullptr;

    int A::m_sTrunkCout = 5;//一次分配五倍

    void * A::operator new(size_t size)

    {

        //核心实现代码

        A* templink;

        if (m_FreePosi == nullptr)

        {

            //待分配内存为空时

            size_t realsize = m_sTrunkCout*size;//一次五倍

            m_FreePosi = reinterpret_cast<A*>(new char[realsize]);

            //一次向系统要5倍的类A字节数大小,不是递归,系统new

            templink = m_FreePosi;

            //将分配出来的内存,彼此之间链表串起来

            for (; templink != &m_FreePosi[m_sTrunkCout - 1]; ++templink)

            {

                //链到最后一个节点空间,结束

                templink->next = templink + 1;

            }

            templink->next = nullptr;

            ++m_iMallocCount;//统计次数

        }

        templink = m_FreePosi;

        m_FreePosi = m_FreePosi->next;

        //既然已经将templink成功返回回去了,就指向下一个能用的内存块

        ++m_iCout;

        return templink;//返回能有的下一块内存

    }

    void A::operator delete(void * phead)

    {

        (static_cast<A*>(phead)->next) = m_FreePosi;

        //将当前要释放的节点指针,指向我下一个空闲块

        m_FreePosi = static_cast<A*>(phead);//始终指向下一个能分配的内存块

        //将m_FreePosi可用空闲块的指针,直接指向了当前要释放的节点

        //意味着后面来申请了,可以直接将这块空间覆盖

        //前面Phead->next已经指向了下一个空闲块,所以m_FreePosi可以直接next到

    }

    void func()

    {

        //测试代码

        clock_t start, end;

        start = clock();

        for (int i = 0; i < 500; i++)

        {

            A *pa = new A();//重载了new

        }

        end = clock();

        cout << "申请分配内存的次数" << A::m_iMallocCount << endl;

        cout << end - start << endl;//测试内存池所用时间

    }

     

    void func1()

    {

        //测试代码

        clock_t start, end;

        start = clock();

        for (int i = 0; i < 5000000; i++)

        {

            A *pa = ::new A();//重载了new

        }

        end = clock();

         

        cout << end - start << endl;//测试普通new所用时间

    }

}

int main()

{

    //_nm::func();

    _nm1::func();

    _nm1::func1();

    getchar();

}

到此这篇关于C++基本组件之内存池详解的文章就介绍到这了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值