133 lines
3.8 KiB
C
133 lines
3.8 KiB
C
|
|
#pragma once
|
||
|
|
#include <QVector>
|
||
|
|
#include <QMutex>
|
||
|
|
#include <QSharedPointer>
|
||
|
|
#include <functional>
|
||
|
|
#include "BZStruct.h"
|
||
|
|
template<typename T>
|
||
|
|
class ObjectPool {
|
||
|
|
public:
|
||
|
|
ObjectPool(size_t initialSize = 100, size_t maxSize = 1000)
|
||
|
|
: m_maxSize(maxSize) {
|
||
|
|
for (size_t i = 0; i < initialSize; ++i) {
|
||
|
|
m_pool.append(new T());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
~ObjectPool() {
|
||
|
|
QMutexLocker lock(&m_mutex);
|
||
|
|
for (auto obj : m_pool) {
|
||
|
|
delete obj;
|
||
|
|
}
|
||
|
|
m_pool.clear();
|
||
|
|
}
|
||
|
|
QSharedPointer<T> acquire() {
|
||
|
|
QMutexLocker lock(&m_mutex);
|
||
|
|
if (!m_pool.isEmpty()) {
|
||
|
|
T* obj = m_pool.takeLast();
|
||
|
|
return QSharedPointer<T>(obj, [this](T* obj) { this->release(obj); });
|
||
|
|
} else if (m_totalCreated < m_maxSize) {
|
||
|
|
m_totalCreated++;
|
||
|
|
T* obj = new T();
|
||
|
|
return QSharedPointer<T>(obj, [this](T* obj) { this->release(obj); });
|
||
|
|
}
|
||
|
|
return QSharedPointer<T>(new T());
|
||
|
|
}
|
||
|
|
size_t size() const {
|
||
|
|
QMutexLocker lock(&m_mutex);
|
||
|
|
return m_pool.size();
|
||
|
|
}
|
||
|
|
size_t totalCreated() const {
|
||
|
|
QMutexLocker lock(&m_mutex);
|
||
|
|
return m_totalCreated;
|
||
|
|
}
|
||
|
|
private:
|
||
|
|
void release(T* obj) {
|
||
|
|
QMutexLocker lock(&m_mutex);
|
||
|
|
if (m_pool.size() < m_maxSize) {
|
||
|
|
*obj = T();
|
||
|
|
m_pool.append(obj);
|
||
|
|
} else {
|
||
|
|
delete obj;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
private:
|
||
|
|
QVector<T*> m_pool;
|
||
|
|
mutable QMutex m_mutex;
|
||
|
|
size_t m_maxSize;
|
||
|
|
size_t m_totalCreated = 0;
|
||
|
|
};
|
||
|
|
class BigOrderInfoPool {
|
||
|
|
public:
|
||
|
|
static BigOrderInfoPool& instance() {
|
||
|
|
static BigOrderInfoPool pool;
|
||
|
|
return pool;
|
||
|
|
}
|
||
|
|
QSharedPointer<BigOrderInfo> acquire() {
|
||
|
|
return m_pool.acquire();
|
||
|
|
}
|
||
|
|
size_t poolSize() const {
|
||
|
|
return m_pool.size();
|
||
|
|
}
|
||
|
|
size_t totalCreated() const {
|
||
|
|
return m_pool.totalCreated();
|
||
|
|
}
|
||
|
|
private:
|
||
|
|
BigOrderInfoPool() : m_pool(100, 500) {}
|
||
|
|
private:
|
||
|
|
ObjectPool<BigOrderInfo> m_pool;
|
||
|
|
};
|
||
|
|
class MemoryMonitor {
|
||
|
|
public:
|
||
|
|
static MemoryMonitor& instance() {
|
||
|
|
static MemoryMonitor monitor;
|
||
|
|
return monitor;
|
||
|
|
}
|
||
|
|
void recordAllocation(size_t bytes, const QString& type) {
|
||
|
|
QMutexLocker lock(&m_mutex);
|
||
|
|
m_allocatedMemory[type] += bytes;
|
||
|
|
m_totalAllocated += bytes;
|
||
|
|
if (m_totalAllocated > m_memoryThreshold && !m_alertTriggered) {
|
||
|
|
emitMemoryAlert();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
void recordDeallocation(size_t bytes, const QString& type) {
|
||
|
|
QMutexLocker lock(&m_mutex);
|
||
|
|
m_allocatedMemory[type] -= bytes;
|
||
|
|
m_totalAllocated -= bytes;
|
||
|
|
}
|
||
|
|
QMap<QString, size_t> getMemoryUsage() const {
|
||
|
|
QMutexLocker lock(&m_mutex);
|
||
|
|
return m_allocatedMemory;
|
||
|
|
}
|
||
|
|
size_t getTotalMemoryUsage() const {
|
||
|
|
QMutexLocker lock(&m_mutex);
|
||
|
|
return m_totalAllocated;
|
||
|
|
}
|
||
|
|
void setMemoryThreshold(size_t threshold) {
|
||
|
|
QMutexLocker lock(&m_mutex);
|
||
|
|
m_memoryThreshold = threshold;
|
||
|
|
}
|
||
|
|
private:
|
||
|
|
void emitMemoryAlert() {
|
||
|
|
m_alertTriggered = true;
|
||
|
|
qWarning() << "Memory usage alert: Total allocated" << m_totalAllocated << "bytes";
|
||
|
|
for (auto it = m_allocatedMemory.begin(); it != m_allocatedMemory.end(); ++it) {
|
||
|
|
if (it.value() > 0) {
|
||
|
|
qWarning() << " " << it.key() << ":" << it.value() << "bytes";
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
private:
|
||
|
|
mutable QMutex m_mutex;
|
||
|
|
QMap<QString, size_t> m_allocatedMemory;
|
||
|
|
size_t m_totalAllocated = 0;
|
||
|
|
size_t m_memoryThreshold = 100 * 1024 * 1024;
|
||
|
|
bool m_alertTriggered = false;
|
||
|
|
};
|
||
|
|
#ifdef MEMORY_TRACKING
|
||
|
|
#define TRACK_MEMORY_ALLOC(bytes, type) MemoryMonitor::instance().recordAllocation(bytes, type)
|
||
|
|
#define TRACK_MEMORY_FREE(bytes, type) MemoryMonitor::instance().recordDeallocation(bytes, type)
|
||
|
|
#else
|
||
|
|
#define TRACK_MEMORY_ALLOC(bytes, type)
|
||
|
|
#define TRACK_MEMORY_FREE(bytes, type)
|
||
|
|
#endif
|