Add MemoryTracker class for memory allocation tracking; integrate with SDL deleters for improved memory management
This commit is contained in:
78
src/app/core/platform/memory_tracker.h
Normal file
78
src/app/core/platform/memory_tracker.h
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
#ifndef YAZE_APP_CORE_PLATFORM_MEMORY_TRACKER_H
|
||||||
|
#define YAZE_APP_CORE_PLATFORM_MEMORY_TRACKER_H
|
||||||
|
|
||||||
|
#include <SDL.h>
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <mutex>
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
namespace yaze {
|
||||||
|
namespace core {
|
||||||
|
|
||||||
|
class MemoryTracker {
|
||||||
|
public:
|
||||||
|
static MemoryTracker& GetInstance() {
|
||||||
|
static MemoryTracker instance;
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TrackAllocation(const void* ptr, size_t size, const char* type) {
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
allocations_[ptr] = {size, type};
|
||||||
|
total_allocated_ += size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TrackDeallocation(const void* ptr) {
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
auto it = allocations_.find(ptr);
|
||||||
|
if (it != allocations_.end()) {
|
||||||
|
total_allocated_ -= it->second.size;
|
||||||
|
allocations_.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t GetTotalAllocated() const {
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
return total_allocated_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DumpAllocations() const {
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
SDL_Log("Memory allocations: %zu bytes in %zu allocations",
|
||||||
|
total_allocated_, allocations_.size());
|
||||||
|
|
||||||
|
std::unordered_map<std::string, size_t> type_counts;
|
||||||
|
for (const auto& pair : allocations_) {
|
||||||
|
type_counts[pair.second.type] += pair.second.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& pair : type_counts) {
|
||||||
|
SDL_Log(" %s: %zu bytes", pair.first.c_str(), pair.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the memory was freed by another reference
|
||||||
|
bool IsFreed(const void* ptr) const {
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
return allocations_.find(ptr) == allocations_.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
MemoryTracker() = default;
|
||||||
|
|
||||||
|
struct AllocationInfo {
|
||||||
|
size_t size;
|
||||||
|
const char* type;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unordered_map<const void*, AllocationInfo> allocations_;
|
||||||
|
size_t total_allocated_ = 0;
|
||||||
|
mutable std::mutex mutex_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace core
|
||||||
|
} // namespace yaze
|
||||||
|
|
||||||
|
#endif // YAZE_APP_CORE_PLATFORM_MEMORY_TRACKER_H
|
||||||
@@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
|
|
||||||
|
#include "app/core/platform/memory_tracker.h"
|
||||||
|
|
||||||
namespace yaze {
|
namespace yaze {
|
||||||
namespace core {
|
namespace core {
|
||||||
|
|
||||||
@@ -14,18 +16,24 @@ struct SDL_Deleter {
|
|||||||
void operator()(SDL_Renderer* p) const { SDL_DestroyRenderer(p); }
|
void operator()(SDL_Renderer* p) const { SDL_DestroyRenderer(p); }
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
// Custom deleter for SDL_Surface
|
||||||
* @brief Deleter for SDL_Texture.
|
struct SDL_Surface_Deleter {
|
||||||
*/
|
void operator()(SDL_Surface* p) const {
|
||||||
struct SDL_Texture_Deleter {
|
if (p && !MemoryTracker::GetInstance().IsFreed(p)) {
|
||||||
void operator()(SDL_Texture *p) const { SDL_DestroyTexture(p); }
|
MemoryTracker::GetInstance().TrackDeallocation(p);
|
||||||
|
SDL_FreeSurface(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
// Custom deleter for SDL_Texture
|
||||||
* @brief Deleter for SDL_Surface.
|
struct SDL_Texture_Deleter {
|
||||||
*/
|
void operator()(SDL_Texture* p) const {
|
||||||
struct SDL_Surface_Deleter {
|
if (p && !MemoryTracker::GetInstance().IsFreed(p)) {
|
||||||
void operator()(SDL_Surface *p) const { SDL_FreeSurface(p); }
|
MemoryTracker::GetInstance().TrackDeallocation(p);
|
||||||
|
SDL_DestroyTexture(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace core
|
} // namespace core
|
||||||
|
|||||||
Reference in New Issue
Block a user