C++메모리 탱크 의 간단 한 실현
1.메모리 풀 이란 무엇 인가
1.1 연못 화 기술
지 화 기술 은 컴퓨터 의 디자인 모델 로 주로 프로그램 에서 자주 사용 해 야 하 는 컴퓨터 자원 을 미리 신청 하고 프로그램 이 스스로 관리 하 며 프로그램 이 사용 할 때'지'에서 직접 얻 는 것 을 말한다.프로그램 이 차지 하 는 자원 의 수량 을 확보 할 뿐만 아니 라 자원 의 신청 과 방출 시간 도 줄 일 수 있다.흔히 볼 수 있 는 연못 화 기술 은 메모리 탱크,스 레 드 탱크,연결 탱크 등 이 있다.
1.2 메모리 풀
메모리 탱크 는 동적 메모리 분배 와 관리 기술 의 하나 다.그것 의 핵심 사상 은 메모리 공간 을 미리 신청 하고 효율 적 인 데이터 구조(해시,링크)를 사용 하여 관리 하 는 것 이다.프로그램 이 메모리 가 필요 할 때 메모리 풀 에서 직접 메모리 공급 프로그램 을 분배 하고 똑 같이 사용 이 끝 났 을 때 메모리 풀 에 돌려 주 는 것 이다.이렇게 하면 new/delete,malloc/freee 등 API 신청 과 메모 리 를 직접 사용 하 는 시간 을 줄 이 고 프로그램 운행 효율 을 높 일 수 있다 는 장점 이 있다.이 동시에 프로그램 은 매번 new/delete,malloc/freee 를 직접 사용 하여 메모리 에서 공간 을 신청 하면 메모리 조각 문 제 를 초래 할 수 있 습 니 다.메모리 탱크 는 큰 메모리 에 직접 신청 하면 메모리 조각 을 줄 일 수 있 습 니 다.
2.메모리 탱크 의 역할
2.1 효율 문제
일반적으로 신청 메모 리 는 new/delete,malloc/free 인 터 페 이 스 를 통 해 메모리 의 더미 에서 메모 리 를 직접 신청 하고 방출 도 더미 에 직접 방출 합 니 다.빈번 한 신청 과 석방 은 반드시 많은 시간 을 소모 하여 프로그램의 운행 효율 을 떨 어 뜨 릴 것 이다.
예 를 들 어 모든 링크 의 노드 크기 가 16 바이트 라 고 가정 하면 링크 가 노드 를 자주 삽입 해 야 할 때 빈번 한 메모리 신청 으로 조작 을 해 야 한다.매번 에 더미 에서 16 개의 바이트 를 신청 할 때마다 일정한 시간 을 써 야 하고 메모 리 를 방출 하 는 데 도 시간 이 필요 하 다.메모리 풀 을 사용 하면 우 리 는 메모리 에서'일부 노드'를 직접 신청 할 수 있 습 니 다.프로그램 이 메모리 가 필요 할 때 직접 쌓 아 올 리 지 않 고 미리 신청 한 메모 리 를 프로그램 에 배분 할 수 있 습 니 다.
2.2 메모리 조각
메모리 에서 작은 메모 리 를 자주 신청 하면 메모리 조각 문제 가 발생 할 수 있 습 니 다.메모리 조각 은 내 조각 과 외 조각 두 가지 로 나 뉜 다.
1)바깥 조각
바깥 조각 은 우리 가 흔히 말 하 는 메모리 조각 이다.예 를 들 어 우 리 는 메모리 에서 16 바이트 크기 의 메모 리 를 신청 할 때마다 메모리 에 16 바이트 크기 의 블록 이 많이 존재 합 니 다.이 메모리 가 방출 될 때 메모리 조각 을 만 들 수 있 습 니 다.다음 그림:
메모리 의 남 은 메모리 크기 는 88 바이트 이지 만,우리 가 신청 할 수 있 는 최대 메모리 블록 은 21 바이트 입 니 다.
2)내부 조각
내부 조각 은 이미 분 배 된 메모리 에 존재 하 는 사용 되 지 않 은 작은 메모리 입 니 다.메모리 탱크 기술 은 메모리 가 자 유 롭 지만 내부 파편 문 제 를 일 으 켰 기 때문에 내부 파편 은 불가피 하지만 프로그램의 최 적 화 를 통 해 메모리 내 파편 을 줄 일 수 있다.
예 를 들 어 실제 수 요 는 10byte 의 메모 리 를 신청 하 는 것 입 니 다.고정 메모리 풀 은 메모리 정렬 을 할 수 있 습 니 다.16 바이트 의 메모 리 를 한꺼번에 분 배 했 습 니 다.나머지 6 바이트 는 실제 사용 하지 않 았 습 니 다.이 6 바이트 는 메모리 내 조각 입 니 다.
3.메모리 탱크 기술 의 발전
1)가장 간단 한 메모리 탱크
남 은 메모 리 를 가리 키 는 링크 를 만 듭 니 다.분 배 는 링크 에서 팝 을 되 돌려 주 는 것 입 니 다.풀 어 주 는 것 은 push 를 링크 에 저장 하 는 것 입 니 다.메모리 의 2 차 방출 문 제 를 방지 하기 위해 서 는 병합,표시,보 호 를 잘 해 야 한다.
2)고정 메모리 풀
FreeList 류 를 실현 합 니 다.그 본질은 링크 입 니 다.노드 는 고정 크기 의 메모리 이 고 머리 삽입 과 머리 삭제 방식 으로 메모리 방출 을 신청 합 니 다.모든 고정 메모리 분배 기 에는 두 개의 링크 가 있 습 니 다.OpenList 는 할당 되 지 않 은 남 은 메모리 대상(FreeList 대상)을 저장 하 는 데 사 용 됩 니 다.CloseList 는 분 배 된 메모리 대상 을 저장 하 는 데 사 용 됩 니 다.
메모리 할당 은 IOpenLsit 에서 대상 을 꺼 내 프로그램 에 주 는 것 입 니 다.메모리 방출 은 대상 push 를 CloseList 에 넣 는 것 입 니 다.메모리 가 부족 할 때 OpenList 는 큰 메모리 가 고정된 길이 의 작은 메모리 로 자 르 는 것 을 신청 합 니 다.
3)C++STL 라 이브 러 리 의 메모리 풀
고정 메모리 풀 에 존재 하 는 문 제 는 고정 길이 의 메모리 만 신청 하 는 것 입 니 다.실제 우리 가 신청 해 야 할 메모리 크기 는 고정 에 관 계 없 이 C+STL 라 이브 러 리 에서 해시 표 와 고정 메모리 풀 을 결합 하 는 방식 으로 메모리 풀 을 실현 할 수 있 습 니 다.구체 적 으로 다음 과 같다.
여러 개의 고정 메모리 풀 을 구성 하고 고정된 정렬 수 로 정렬 합 니 다(예 를 들 어 8 바이트 로 정렬 합 니 다).첫 번 째 고정 메모리 풀 의 메모리 대상 크기 는 8 입 니 다(적어도 64 비트 든 32 비트 시스템 에서 다음 포인터 형식 을 저장 할 수 있 도록 보장 해 야 합 니 다).두 번 째 메모리 풀 의 대상 크기 는 16 입 니 다.마지막 메모리 풀 의 대상 크기 는 128 byte 입 니 다.신청 한 메모리 크기 가 128 바이트 가 넘 으 면 2 급 공간 설정 기 를 통 해 신청 합 니 다(메모리 에서 직접 신청 합 니 다).
해시 시 계 를 만들어 서 서로 다른 크기 의 메모리 대상 을 해시 표 에 걸 어 라.다음 그림:
신청 메모리:신청 할 메모리 크기 는 8 바이트 로 index 에 직접 있 습 니 다. = 0 곳 에서 메모 리 를 분배 합 니 다.물론 신청 한 메모리 가 8 바이트 보다 적 을 때 도 8 바이트 의 메모 리 를 직접 분배 합 니 다.자유list[index]nullptr 일 때 메모리 에서 메모 리 를 신청 하여 고정 크기 로 자 르 고'Free'에 걸 기list[index]위치.
메모리 방출:메모리 대상 크기 에 따라 index 가 해시 표 에 삽 입 된 index 위 치 를 계산 합 니 다.
2.간이 메모리 탱크 원리
1.전체적인 디자인
1.1 메모리 풀 구조
두 개의 링크,RequestMemory 와 Release Memory.
RequestMemory 링크 는 new 나 malloc 를 사용 하여 물리 적 메모리 에서 신청 한 아직 사용 되 지 않 은 메모리 블록 으로 memNode 노드 입 니 다.
Release Memory 링크 는 방출 된 고정 크기 의 메모리 블록 을 사용 하여 저장 합 니 다.
1.2 메모리 신청
1.3 메모리 사용
메모 리 를 풀 때 방출 할 메모 리 를 Release Memory 의 머리 부분 에 직접 푸 시 하면 됩 니 다.
2.상세 분석
2.1 blockNode 구조
BlockNode 는 새로 신청 한 메모리 블록 을 구조 체 로 관리 하 는 것 을 표시 합 니 다.blockNode 멤버 는 다음 과 같 습 니 다:
2.2 개체 크기
여기 서 단일 대상 이 가리 키 는 ReleaseMemory 의 노드 크기 는 사용자 가 신청 한 메모리 크기 sizeof(T)가 sizeof(T*)보다 작 을 때 이 대상 을 ReleaseMemory 에 연결 할 수 있 도록 T*에 따라 배분 해 야 합 니 다.
3.성능 비교
각각 malloc/free,new/delete,memPool 신청 과 110000 개의 메모 리 를 사용 합 니 다.시간 은 다음 과 같 습 니 다.
3.간이 메모리 풀 전체 소스 코드
#include<iostream>
#include<vector>
#include<ctime>
using namespace std;
template<class T>
class MemPool
{
private:
//
typedef struct BlockNode
{
void* _memory;//
BlockNode* _next;// blockNode
size_t _objNum;//
// ---num
BlockNode(size_t num)
:_objNum(num),
_next(nullptr)
{
_memory = malloc(_objNum*_size);
}
~BlockNode()
{
free(_memory);
_memory = nullptr;
_next = nullptr;
_objNum = 0;
}
}BlockNode;
protected:
static size_t _size;//
T* _releaseMemory = nullptr;//
BlockNode* _requestMemory;//
size_t _maxNum;//
size_t _useCount;//
protected:
//
static size_t setSize()
{
return (sizeof(T) >= sizeof(T*) ? sizeof(T):sizeof(T*));
}
public:
MemPool()
:_useCount(0),
_releaseMemory(nullptr),
_maxNum(100000*_size)
{
// 32 _size
_requestMemory = new BlockNode(32);
}
~MemPool()
{
BlockNode *cur = _requestMemory;
while (cur)
{
BlockNode* del = cur;
cur = cur->_next;
delete del; // ~BlockNode()
}
}
T* New()
{
// releaseMemory
if (_releaseMemory)
{
T* obj = _releaseMemory;
_releaseMemory = *((T**)_releaseMemory);//releaseMemory
return obj;
}
else
{
// requesetMemory
if (_requestMemory->_objNum == _useCount)
{
//
size_t size = 2 * _useCount >= _maxNum ? _maxNum : 2 * _useCount;
BlockNode* newBlock = new BlockNode(size);
newBlock->_next = _requestMemory;
_requestMemory = newBlock;
_useCount = 0;
}
// ,
T* obj = (T*)((char*)_requestMemory->_memory+_useCount*_size);
_useCount++;
return new(obj)T();// new
}
}
void Delete(T* obj)
{
if (obj)
{
obj->~T();
*((T**)obj) = _releaseMemory;
_releaseMemory = obj;
}
}
};
// ,
template<typename T>
size_t MemPool<T>::_size = MemPool<T>::setSize();
struct TreeNode
{
int _val;
TreeNode* _left;
TreeNode* _right;
};
void test1()
{
MemPool<TreeNode> mp;
vector<TreeNode*> v;
for (int i = 0; i < 10; i++)
{
TreeNode* mem = mp.New();
v.push_back(mem);
}
for (int i = 0; i < 10; i++)
{
mp.Delete(v[i]);
}
}
C++메모리 풀 의 간단 한 실현 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 C+메모리 풀 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 많은 응원 바 랍 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Visual Studio에서 파일 폴더 구분 (포함 경로 설정)Visual Studio에서 c, cpp, h, hpp 파일을 폴더로 나누고 싶었습니까? 어쩌면 대부분의 사람들이 있다고 생각합니다. 처음에 파일이 만들어지는 장소는 프로젝트 파일 등과 같은 장소에 있기 때문에 파일...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.