关于仿照java的内存回收机制实现C++的自动内存回收的一点想法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于仿照java的内存回收机制实现C++的自动内存回收的一点想法相关的知识,希望对你有一定的参考价值。

  java的内存回收机制是很高效的,对软件产生的额外影响很小。而在C++中的大多数智能指针都是采用的引用计数的策略实现,当计数到0时,将所指向的指针删除。这种智能指针当应用到比较大的对象或者动态内存分配的次数非常少时。对软件的性能不会有多大的影响,反而提高了对内存的使用效率。可是一旦使用动态内存分配的次数非常巨大的时候。不仅对内存的使用效率下降,软件的运行效率也会下降很多。这主要是因为,动态分配造成的存储碎片化使可用内存减少,cache命中率也会下降。对软件性能可能会造成几百倍的损失。

  目前的想法是设计一个自定义的堆,它用字节数组来实现。将用于管理动态内存的核和小的对象的存储空间在自定义堆栈进行分配,大的对象在系统堆中进行分配。而自定义堆对应的智能指针只负责引用计数的处理,不负责删除指针。删除指针的操作由自定义堆进行,自定义堆按时对引用计数小于1的核和核指针指向的对象进行删除。这样存储的碎片化问题可以得到部分解决。同时,智能指针的效率也会提高。同时,对cache的命中率也有提升作用。

现附上本人的已实现的部分代码

//pointtype.hpp

//#include"mem_malloc.hpp"
#ifndef __POINTTYPE__
#define __POINTTYPE__
#include<iostream>
//#include"mem_malloc.hpp"
namespace  smart_point{

#define ptr_new(type,init_argv) (new type(init_argv))
template<typename T>
struct mem_struct{
	int quote_count;
	T   data;
};

template<typename T>
class Ptr{	
protected:
	T* p_data;
	int  *count;
	//static heap*h;
public:
	//static void set_heap(heap*h){
		//this->h=h;
	//}
	Ptr(T*data){
		p_data=data;
		count=new int(1);
	//std::cout<<this->p_data<<"被引用的次数是:"<<*count<<std::endl;
	}
	Ptr(Ptr<T> &p){
		p_data=p.p_data;
		count=p.count;
		(*count)++;
		//std::cout<<this->p_data<<"被引用的次数是:"<<*count<<std::endl;

	}
	void operator =(Ptr<T> &p){
		if((--(*count))<=0){
			//std::cout<<this->p_data<<"被引用的次数是:"<<*count<<std::endl;
			delete p_data;
			delete count;
			
		}
		p_data=p.p_data;
		count=p.count;
		(*count)++;
		//std::cout<<this->p_data<<"被引用的次数是:"<<*count<<std::endl;
	}
	T& operator*(){
		return *(this->p_data);
	}
	void operator =(T*data){
		if((--(*count))<=0){
			delete p_data;
			delete count;
		}
		p_data=data;
		count=new int(1);
		//std::cout<<this->p_data<<"被引用的次数是:"<<*count<<std::endl;
		
	}
	T* operator ->(){
		return this->p_data;
	}
	T& get(){
		return *p_data;
	}
	T& v(){
		return *p_data;
	}
	T*return_point(){
		return p_data;
	}
	~Ptr(){
		if((--(*count))<=0){
			//std::cout<<this->p_data<<"被引用的次数是:"<<*count<<std::endl;
			delete p_data;
			delete count;
			
		}
	}
};
//template<typename T>
 //heap * Ptr<T>::h=NULL;
};

#endif

 mem_malloc.hpp

#ifndef  __MEM_MALLOC__
#define __MEM_MALLOC__
#include<iostream>
#include<fstream>

//#define _new(h,type) ::new ((type*)h.malloc(sizeof(type))) type()
#define __new__(__heap__,__type__,__init_argv__) ::new ((__type__*)__heap__.malloc(sizeof(__type__))) __type__(__init_argv__)
#define _new(_heap,_type,init_argv) __new__(_heap,_type,init_argv)

#define __delete__(__heap__,__type__,__val__) (__heap__.free((void*)__val__,sizeof(__type__)))
#define _object_del(_heap,_type,_val) (_val)->~_type();__delete__(_heap,_type,_val)
#define _delete(_heap,_type,_val) __delete__(_heap,_type,_val)
class heap{
    char *bit_map;
    char* heap_block;
    int block_size;
    int free_size;
private:
    bool bit_map_set(int loc,int length);
    bool bit_map_clr(int loc,int length);
    int  find_freeblock(int size);
public:
    heap(int size);
    void *malloc(int size){
        int index=this->find_freeblock(size);
        if(index>=0){
            this->bit_map_set(index,size);
            this->free_size-=size;
            //std::cout<<"the free space of my heap has  "<<free_size<<std::endl;
            void * answer=(void*)(this->heap_block+index);
            return answer;
        }
        else{
            return NULL;
        }
    }
    void free(void*p,int size){
        bit_map_clr((int)((char*)p-(this->heap_block)),size);
    }
    void print(std::ostream& out){
        out<<std::hex;
        for(int i=0;i<((this->block_size)-(this->free_size));i+=sizeof(char)){
            out.width(2);
            out.fill(0);
            out<<((unsigned short)(*(this->heap_block+i))&(0x0f))<< ;
        }
        out<<std::dec;
    }
    void source_print(std::ostream& out){
        for(int i=0;i<((this->block_size)-(this->free_size));i+=sizeof(long)){
            out<<std::hex;
            out.width(8);
            out.fill(0);
            out<<(long*)(this->heap_block+i)<<":";
            out.width(8);
            out.fill(0);
            out<<((long)(*(this->heap_block+i)))<<std::endl;
        }
        out<<std::dec;
    }
    
        void char_print(std::ostream&out){
            for(int i=0;i<block_size/8;i++){
                out<<std::hex;
                out.widen(2);
                //out.fill(‘0‘);
                out<<"0x"<<(unsigned short)(*(bit_map+i)&0xff)<<" ";

            }
            out<<std::dec<<std::endl;
            
        }
    ~heap(){delete[] heap_block;
    delete[] bit_map;
    }
};
heap::heap(int size){
    heap_block=new char[size];
    bit_map=new char[(int)(size/8.0+0.5)];
    std::fill(bit_map,bit_map+(int)(size/8.0+0.5),0x00);
    block_size=size;
    free_size=size;
    }
bool heap::bit_map_set(int loc,int length){
#define set_bit_at(val,index) (val|(0x01<<(index%8)))
    for(int i=loc;i<loc+length;i++){
        bit_map[i/8]= set_bit_at(bit_map[i/8],i);
    }
    return true;
}
bool heap::bit_map_clr(int loc,int length){
    #define clr_bit_at(val,index) (char)((val)&(~((unsigned char)0x01<<(index%8))))
    for(int i=loc;i<loc+length;i++){
        if(i>=(int)(block_size/8.0+0.5))
            return false;
        bit_map[i/8]= clr_bit_at(bit_map[i/8],i);
    }
    return true;
}
int  heap::find_freeblock(int size){
#define return_bit_at(val,index) (((val>>(index%8))&0x01)==0x01?true:false)
    bool continuation_state=true;
    int count=0;
    int loc=0;
    for(int i=0;i<this->block_size;i++){
        if(!return_bit_at(bit_map[i/8],i)){
            count++;
        }else{
            count=0;
            loc=i;
        }
        if(count>=size)
            return loc;
    }
    return -1;
}

class delete_function{
    heap &_heap;
public:
    delete_function(heap&def_heap):_heap(def_heap){ 
    }
    template<typename T>
    void operator ()(T*p){
    _object_del(_heap,T,p);
    }
    template<typename T>
    void operator ()(heap&def_heap,T*p){
    _object_del(def_heap,T,p);
    }
} ;
class new_function{
        heap &_heap;
public:
    new_function(heap&def_heap):_heap(def_heap){ 
    }
    template<typename T>
    void operator ()(){
    _new(_heap,T);
    }
};
heap default_heap(1024);
delete_function delete_(default_heap);
//new_function   new_(default_heap);
//#define __new(type) _new(Heap,type)
#define        __objdel(_type,_val)                _object_del(Heap,_type,_val)//自定义对象析构
#define            del(_heap_,_val)                                  delete_(_heap_,_val)  //删除在堆Heap上的一个对象
#define            alloc(_heap_,_type,_init_argv)      _new(_heap_,_type,_init_argv)//分配给对象type一块内存
#define    new_(_type_,_init_argv_)     _new(default_heap,_type_,_init_argv_)
#endif 
#pragma once
class NullClass
{
    static int count;
    int id;
public:
    NullClass(void);
    ~NullClass(void);
};
#include "NullClass.h"
#include<iostream>

int NullClass::count=0;
NullClass::NullClass(void)
{
    this->id=count++;
    std::cout<<"创建了id="<<id<<"的一个NullClass对象!"<<std::endl;
}


NullClass::~NullClass(void)
{
    std::cout<<"删除了id="<<id<<"的一个NullClass对象!"<<std::endl;
}
#include<iostream>
#include<string>
#include<vector>
#include<iterator>
#include"NullClass.h"
//%%%%%%%%%%%%%%%%%%%%
#include"pointtype.hpp"
#include"mem_malloc.hpp"
using namespace smart_point;
//%%%%%%%%%%%%%%%%%%%%
using namespace std;
int main(int argc,char*argv[]){
    heap sys_m(1024);
    string*                p1            =        new string("\t这是使用C++提供的方法来动态创建的string对象");
    Ptr<string>        p2            =        new string("\t这将是一个被智能指针Ptr引用的动态创建的string对象!");
    string*                p3            =        new_(string,"\t这是一个用自定义的默认堆创建的string对象!");
    string *            p4            =        alloc(sys_m,string,"\t这是一个使用指定的堆动态创建的string对象!");
    cout<<"p1 ->:"<<*p1<<endl;
    cout<<"p2 ->:"<<*p2<<endl;
    cout<<"p3 ->:"<<*p3<<endl;
    cout<<"p4 ->:"<<*p4<<endl;
    delete p1;//调用C++提供的释放方法来删除对象
    delete_(p3);//调用自己实现的默认的堆的释放方法来删除对象
    //delete_(sys_m,p4);//调用实现的对应的堆释放方法来删除对象
    NullClass *c1=new(NullClass);
    NullClass*c2=new_(NullClass);
    NullClass*c3=alloc(sys_m,NullClass);
    cout<<"default_heap:\n";
    default_heap.char_print(cout);
    cout<<endl;
    default_heap.source_print(cout);
    cout<<"sys_m:\n";
    sys_m.char_print(cout);
    cout<<endl;
    sys_m.source_print(cout);
    //cout<<(*pint).v()<<endl;
    delete(c1);
    //delete_(c2);
    delete_(sys_m,c3);
    //p1使用了引用计数的技术,由Ptr智能指针负责在合适的时间来删除被引用的对象
    cout<<endl;
    char str[]="hello,world!";
    for(int i=0;i<10;i++){
        string *p=new_(string,str,str+(10-i));
        default_heap.char_print(cout);
        delete_(p);
        
    }
    cin.get();
    return 0;
}

 

以上是关于关于仿照java的内存回收机制实现C++的自动内存回收的一点想法的主要内容,如果未能解决你的问题,请参考以下文章

Java我可以主动去释放对象占的内存吗?可以的怎释放?

内存泄漏与内存溢出

Java的垃圾回收机制

Java垃圾回收机制

Java垃圾回收机制

Java垃圾回收机制