问题描述
Electronic Arts EASTL 图书馆的 east::allocator
需要用户实现一个特殊的 new
运算符(如这个 示例).这个 new
运算符有一个 const char* name
,它应该用于记录有关内存 分配 执行 EASTL 容器的应用程序特定信息.EASTL 最佳实践指南也提到应该命名容器以跟踪内存使用情况."
The Electronic Arts EASTL library's east::allocator
requires the user to implement a special new
operator (as shown in this sample). This new
operator has a const char* name
, which is supposed to be used to log application-specific information about memory allocations performed EASTL containers. The EASTL Best Practices guide also mentions that one should "Name containers to track memory usage."
然而,eastl::allocator::deallocate
似乎没有任何对应的const char* name
传递,所以似乎没有一个build- 记录内存解除分配的方式.
However, there does not appear to be any corresponding const char* name
passed by eastl::allocator::deallocate
, so there does not appear to be a built-in way to log memory deallocations.
这个 EASTL 调试功能打算如何使用?我想我一定错过了一些东西.一位 EA 软件工程师也在 2015 年进行了相关的演示,展示了一些内部工具由 EA 开发用于内存调试,似乎建议他们同时跟踪分配和释放(例如,确保在游戏级别 2"开始时释放游戏级别 1"的内存).
How is this EASTL debugging functionality intended to be used? I think I must be missing something. An EA Software Engineer also gave a related presentation in 2015, where he showed some internal tools developed by EA for memory debugging, and it seems to suggest that they tracking both allocations and deallocations (for example, to ensure that the memory for "game level 1" is freed when "game level 2" begins).
推荐答案
EASTL 的分配器是有状态的并且绑定到容器的实例;这意味着它们是在实例级别定义的:
The allocators by the EASTL are stateful and bound to the instance of the container; meaning they are defined at instance level:
EASTL 所做的是使用更熟悉的内存分配模式因此只有一个分配器类接口,它由所有容器.此外,EASTL 容器可让您访问它们的分配器并查询它们、命名它们、更改它们等.
EASTL 选择使分配器不在容器之间复制在容器交换和分配操作期间.这意味着如果容器 A 与容器 B 交换其内容,两个容器保留其原始分配器.类似地,将容器 A 分配给容器 B 使容器 B 保留其原始分配器.等效的容器应通过 operator== 报告;东航如果分配器相等,将进行智能交换,并进行蛮力交换否则.
EASTL has chosen to make allocators not be copied between containers during container swap and assign operations. This means that if container A swaps its contents with container B, both containers retain their original allocators. Similarly, assigning container A to container B causes container B to retain its original allocator. Containers that are equivalent should report so via operator==; EASTL will do a smart swap if allocators are equal, and a brute-force swap otherwise.
来自 https://github.com/questor/Eastl/blob/master/doc/EASTL%20Design.html
所以我会向分配器类添加一个成员并跟踪其中的内存计数,如下所示:
So I would add a member to the allocator class and track the memory count inside it, like following:
#ifndef EASTL_CUSTOM_ALLOCATOR_H_
#define EASTL_CUSTOM_ALLOCATOR_H_
#include "new_implementation.hpp"
#include <EASTL/list.h>
#include <iostream>
#define DEBUG_MACRO
class EASTL_CustomAllocator {
public:
EASTL_CustomAllocator(const char* pName = EASTL_NAME_VAL(EASTL_ALLOCATOR_DEFAULT_NAME))
: m_pName(pName), m_totalAmountOfBytesAllocated(0) {
#ifdef DEBUG_MACRO
std::cout << m_pName << ": default construct allocator" << std::endl;
#endif
}
EASTL_CustomAllocator(const EASTL_CustomAllocator& x)
: m_pName(x.m_pName),
m_totalAmountOfBytesAllocated(x.m_totalAmountOfBytesAllocated) {
#ifdef DEBUG_MACRO
std::cout << m_pName << ": copy construct allocator" << std::endl;
#endif
}
EASTL_CustomAllocator(const EASTL_CustomAllocator& x, const char* pName)
: m_pName(pName),
m_totalAmountOfBytesAllocated(x.m_totalAmountOfBytesAllocated) {
#ifdef DEBUG_MACRO
std::cout << m_pName << ": copy construct allocator" << std::endl;
#endif
}
EASTL_CustomAllocator& operator=(const EASTL_CustomAllocator& x) {
#ifdef DEBUG_MACRO
std::cout << m_pName << ": copy assignment" << std::endl;
#endif
m_pName = x.m_pName;
m_totalAmountOfBytesAllocated = x.m_totalAmountOfBytesAllocated;
return *this;
}
void* allocate(size_t num_of_bytes, int flags = 0) {
m_totalAmountOfBytesAllocated += num_of_bytes;
void* p = ::new((char*)0, flags, 0, (char*)0, 0) char[num_of_bytes];
#ifdef DEBUG_MACRO
std::cout << m_pName << ": allocate " << num_of_bytes << " bytes" << " at: " << (void*) p << std::endl;
#endif
return p;
}
void* allocate(size_t num_of_bytes, size_t alignment, size_t offset, int flags = 0) {
m_totalAmountOfBytesAllocated += num_of_bytes;
void* p = ::new(alignment, offset, (char*)0, flags, 0, (char*)0, 0) char[num_of_bytes];
#ifdef DEBUG_MACRO
std::cout << m_pName << ": allocate " << num_of_bytes << " bytes" << " at: " << (void*) p << std::endl;
#endif
return p;
}
void deallocate(void* p, size_t num_of_bytes) {
m_totalAmountOfBytesAllocated -= num_of_bytes;
#ifdef DEBUG_MACRO
std::cout << m_pName << ": deallocate " << num_of_bytes << " bytes" << " at: " << (void*) p << std::endl;
#endif
delete[](char*)p;
}
const char* get_name() const {
return m_pName;
}
void set_name(const char* pName) {
m_pName = pName;
}
size_t get_totalAmountOfBytesAllocated() const {
return m_totalAmountOfBytesAllocated;
}
protected:
const char* m_pName; // Debug name, used to track memory.
size_t m_totalAmountOfBytesAllocated; // keeps track of the memory currently allocated
};
bool operator==(const EASTL_CustomAllocator& a, const EASTL_CustomAllocator& b) {
if (&a == &b) {
return true; // allocator a and b are equal if they are the same
}
else {
return false; // otherwhise, return false, because the state m_totalAmountOfBytesAllocated needs to be increased/decreased on splice and swap
}
}
bool operator!=(const EASTL_CustomAllocator& a, const EASTL_CustomAllocator& b) {
return false;
}
#endif /* EASTL_CUSTOM_ALLOCATOR_H_ */
将该自定义分配器类型作为模板参数传递给如以下的东西(您也可以在构造时使用用户定义的名称设置实例,甚至稍后通过 set_allocator()):
Pass that custom allocator type as a template parameter to a eastl container like following (also you can set a instance with a user-defined name at construction and even later by set_allocator()):
eastl::list<int, EASTL_CustomAllocator>
list(EASTL_CustomAllocator("EASTL Some Name"));
但我不确定如何使用调试功能.
But I'm not sure how the debugging functionality is intended to be used.
这篇关于如何使用 EASTL 跟踪内存使用情况?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!