DataArray, DataObject pool 적용. 버그 수정. AGV 움직임 튀는 거 수정 필요
This commit is contained in:
144
Assets/Scripts/UVC/Data/DataObjectPool.cs
Normal file
144
Assets/Scripts/UVC/Data/DataObjectPool.cs
Normal file
@@ -0,0 +1,144 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UVC.Data
|
||||
{
|
||||
/// <summary>
|
||||
/// DataObject 인스턴스를 재사용하기 위한 객체 풀 클래스입니다.
|
||||
/// 메모리 할당과 가비지 컬렉션을 최소화하기 위해 DataObject 인스턴스를 관리합니다.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 객체 풀링은 자주 생성 및 삭제되는 객체의 성능을 향상시키는 패턴입니다.
|
||||
/// 사용이 끝난 객체를 삭제하는 대신 풀에 반환하고, 새 객체가 필요할 때 풀에서 꺼내 재사용합니다.
|
||||
/// </remarks>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// // 객체 풀에서 DataObject 가져오기
|
||||
/// DataObject obj = DataObjectPool.Get();
|
||||
///
|
||||
/// // 객체 사용
|
||||
/// obj["name"] = "홍길동";
|
||||
/// obj["age"] = 30;
|
||||
///
|
||||
/// // 작업 완료 후 풀에 반환
|
||||
/// DataObjectPool.Return(obj);
|
||||
///
|
||||
/// // 풀 통계 확인
|
||||
/// ULog.Debug(DataObjectPool.GetStats());
|
||||
/// </code>
|
||||
/// </example>
|
||||
public static class DataObjectPool
|
||||
{
|
||||
/// <summary>
|
||||
/// DataObject 인스턴스를 저장하는 스레드 안전 큐입니다.
|
||||
/// </summary>
|
||||
private static ConcurrentQueue<DataObject> dataObjectPool = new ConcurrentQueue<DataObject>();
|
||||
|
||||
/// <summary>
|
||||
/// 풀의 최대 크기입니다. 이 크기를 초과하는 객체는 풀에 저장되지 않습니다.
|
||||
/// </summary>
|
||||
private static int maxPoolSize = 1000;
|
||||
|
||||
// --- 통계용 필드 ---
|
||||
private static int _inUseCount = 0;
|
||||
private static int _peakUsage = 0;
|
||||
private static int _poolMisses = 0;
|
||||
private static readonly object _statsLock = new object();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 풀의 최대 크기를 설정합니다.
|
||||
/// </summary>
|
||||
/// <param name="size">설정할 최대 크기</param>
|
||||
public static void SetMaxPoolSize(int size)
|
||||
{
|
||||
maxPoolSize = size > 0 ? size : 1000;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 풀에서 DataObject 인스턴스를 가져옵니다.
|
||||
/// 풀이 비어있으면 새 인스턴스를 생성하여 반환합니다.
|
||||
/// </summary>
|
||||
/// <returns>재사용 가능한 DataObject 인스턴스</returns>
|
||||
public static DataObject Get()
|
||||
{
|
||||
bool fromPool = dataObjectPool.TryDequeue(out var obj);
|
||||
|
||||
lock (_statsLock)
|
||||
{
|
||||
_inUseCount++;
|
||||
if (_inUseCount > _peakUsage)
|
||||
{
|
||||
_peakUsage = _inUseCount;
|
||||
}
|
||||
|
||||
// 풀이 비어있어서 새 객체를 만들어야 하는 경우
|
||||
if (!fromPool)
|
||||
{
|
||||
_poolMisses++;
|
||||
// 현재 사용량이 최대 풀 크기에 도달했는지 확인
|
||||
if (_inUseCount > maxPoolSize)
|
||||
{
|
||||
int oldSize = maxPoolSize;
|
||||
maxPoolSize += 1000;
|
||||
Debug.Log($"DataObjectPool size automatically increased from {oldSize} to {maxPoolSize}. Peak usage: {_peakUsage}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_peakUsage % 100 == 0) Debug.Log($"DataObjectPool stats: {GetStats()}");
|
||||
|
||||
if (fromPool)
|
||||
{
|
||||
obj.IsInPool = false;
|
||||
obj.Reset();
|
||||
}
|
||||
return fromPool ? obj : new DataObject();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 사용이 완료된 DataObject를 풀에 반환합니다.
|
||||
/// 객체는 반환 전에 초기화되어 모든 속성이 제거됩니다.
|
||||
/// </summary>
|
||||
/// <param name="obj">풀에 반환할 DataObject 인스턴스</param>
|
||||
public static void Return(DataObject obj)
|
||||
{
|
||||
if (obj == null || obj.IsInPool) return;
|
||||
|
||||
lock (_statsLock)
|
||||
{
|
||||
_inUseCount--;
|
||||
}
|
||||
|
||||
if (dataObjectPool.Count < maxPoolSize)
|
||||
{
|
||||
obj.Reset(); // 재사용 전 완벽한 초기화
|
||||
obj.IsInPool = true;
|
||||
dataObjectPool.Enqueue(obj);
|
||||
}
|
||||
// 풀이 가득 차면 객체는 풀에 추가되지 않고 GC 대상이 됩니다.
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 풀의 현재 성능 통계를 문자열로 반환합니다.
|
||||
/// </summary>
|
||||
/// <returns>풀 통계 (최대 사용량, 현재 사용량, 풀 비어있을 때 생성 횟수, 현재 풀 크기)</returns>
|
||||
public static string GetStats()
|
||||
{
|
||||
return $"Peak Usage: {_peakUsage}, In Use: {_inUseCount}, Misses: {_poolMisses}, Pooled: {dataObjectPool.Count}, Max Size: {maxPoolSize}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 풀 통계를 초기화합니다.
|
||||
/// </summary>
|
||||
public static void ResetStats()
|
||||
{
|
||||
lock (_statsLock)
|
||||
{
|
||||
_peakUsage = 0;
|
||||
_poolMisses = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user