【cfg】 解决FileRecordCacheManager不清除缓存,导致内存占用缓慢无限增大的bug
parent
e36468dcc8
commit
ee217e1a32
|
|
@ -33,8 +33,6 @@ namespace Luban.Client
|
||||||
|
|
||||||
private static NLog.Logger s_logger;
|
private static NLog.Logger s_logger;
|
||||||
|
|
||||||
private static MultiFileWatcher s_watcher;
|
|
||||||
|
|
||||||
private static void PrintUsage(string err)
|
private static void PrintUsage(string err)
|
||||||
{
|
{
|
||||||
Console.WriteLine("ERRORS:");
|
Console.WriteLine("ERRORS:");
|
||||||
|
|
@ -166,7 +164,7 @@ Options:
|
||||||
{
|
{
|
||||||
GenOnce(options, profile);
|
GenOnce(options, profile);
|
||||||
|
|
||||||
s_watcher = new MultiFileWatcher(options.WatchDir, () => GenOnce(options, profile));
|
new MultiFileWatcher(options.WatchDir, () => GenOnce(options, profile));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ using Luban.Job.Cfg.Datas;
|
||||||
using Luban.Job.Cfg.Defs;
|
using Luban.Job.Cfg.Defs;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace Luban.Job.Cfg.Cache
|
namespace Luban.Job.Cfg.Cache
|
||||||
{
|
{
|
||||||
|
|
@ -13,9 +14,30 @@ namespace Luban.Job.Cfg.Cache
|
||||||
{
|
{
|
||||||
private static readonly NLog.Logger s_logger = NLog.LogManager.GetCurrentClassLogger();
|
private static readonly NLog.Logger s_logger = NLog.LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
|
private const int CACHE_FILE_LOW_WATER_MARK = 5000;
|
||||||
|
private const int CACHE_FILE_HIGH_WATER_MARK = 8000;
|
||||||
|
|
||||||
public static FileRecordCacheManager Ins { get; } = new FileRecordCacheManager();
|
public static FileRecordCacheManager Ins { get; } = new FileRecordCacheManager();
|
||||||
|
|
||||||
private readonly ConcurrentDictionary<(string, string, string, bool), (DefTable, List<DType>)> _caches = new ConcurrentDictionary<(string, string, string, bool), (DefTable, List<DType>)>();
|
class FileRecordCache
|
||||||
|
{
|
||||||
|
public DefTable Table { get; }
|
||||||
|
|
||||||
|
public List<DType> Records { get; }
|
||||||
|
|
||||||
|
public volatile int LastAccessTime;
|
||||||
|
|
||||||
|
public FileRecordCache(DefTable table, List<DType> records)
|
||||||
|
{
|
||||||
|
Table = table;
|
||||||
|
Records = records;
|
||||||
|
LastAccessTime = Bright.Time.TimeUtil.Now;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly ConcurrentDictionary<(string, string, string, bool), FileRecordCache> _caches = new ConcurrentDictionary<(string, string, string, bool), FileRecordCache>();
|
||||||
|
|
||||||
|
private readonly object _shrinkLocker = new object();
|
||||||
|
|
||||||
public bool TryGetCacheLoadedRecords(DefTable table, string md5, string originFile, string sheetName, bool exportTestData, out List<DType> cacheRecords)
|
public bool TryGetCacheLoadedRecords(DefTable table, string md5, string originFile, string sheetName, bool exportTestData, out List<DType> cacheRecords)
|
||||||
{
|
{
|
||||||
|
|
@ -25,9 +47,10 @@ namespace Luban.Job.Cfg.Cache
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (r.Item1.ValueTType.GetBeanAs<DefBean>().IsDefineEquals(table.ValueTType.GetBeanAs<DefBean>()))
|
r.LastAccessTime = Bright.Time.TimeUtil.Now;
|
||||||
|
if (r.Table.ValueTType.GetBeanAs<DefBean>().IsDefineEquals(table.ValueTType.GetBeanAs<DefBean>()))
|
||||||
{
|
{
|
||||||
cacheRecords = r.Item2;
|
cacheRecords = r.Records;
|
||||||
s_logger.Trace("hit cache. table:{table} file:{file} md5:{md5}", table.FullName, originFile, md5);
|
s_logger.Trace("hit cache. table:{table} file:{file} md5:{md5}", table.FullName, originFile, md5);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -39,7 +62,30 @@ namespace Luban.Job.Cfg.Cache
|
||||||
|
|
||||||
public void AddCacheLoadedRecords(DefTable table, string md5, string sheetName, bool exportTestData, List<DType> cacheRecords)
|
public void AddCacheLoadedRecords(DefTable table, string md5, string sheetName, bool exportTestData, List<DType> cacheRecords)
|
||||||
{
|
{
|
||||||
_caches[(table.Assembly.TimeZone.Id, md5, sheetName, exportTestData)] = (table, cacheRecords);
|
lock (_shrinkLocker)
|
||||||
|
{
|
||||||
|
_caches[(table.Assembly.TimeZone.Id, md5, sheetName, exportTestData)] = new FileRecordCache(table, cacheRecords);
|
||||||
|
if (_caches.Count > CACHE_FILE_HIGH_WATER_MARK)
|
||||||
|
{
|
||||||
|
s_logger.Info("ShrinkCaches. cache count > high CACHE_FILE_HIGH_WATER_MARK:{}", CACHE_FILE_HIGH_WATER_MARK);
|
||||||
|
ShrinkCaches();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ShrinkCaches()
|
||||||
|
{
|
||||||
|
if (_caches.Count < CACHE_FILE_HIGH_WATER_MARK)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var cacheList = _caches.ToList();
|
||||||
|
cacheList.Sort((a, b) => a.Value.LastAccessTime - b.Value.LastAccessTime);
|
||||||
|
for (int i = 0; i < CACHE_FILE_HIGH_WATER_MARK - CACHE_FILE_LOW_WATER_MARK; i++)
|
||||||
|
{
|
||||||
|
_caches.Remove(cacheList[i].Key, out _);
|
||||||
|
}
|
||||||
|
s_logger.Info("ShrinkCaches. after shrink, cache file num:{}", _caches.Count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue