Improved GameFileCache memory usage

This commit is contained in:
dexy 2019-12-11 00:31:56 +11:00
parent d5c0bc2477
commit 0aa220e0c2
8 changed files with 67 additions and 7 deletions

View File

@ -226,6 +226,10 @@ namespace CodeWalker.GameFiles
//{ }
#endregion
#if !DEBUG
Meta = null;
#endif
}

View File

@ -2257,6 +2257,13 @@ namespace CodeWalker.GameFiles
}
public void BeginFrame()
{
lock (requestSyncRoot)
{
mainCache.BeginFrame();
}
}
public bool ContentThreadProc()

View File

@ -11,7 +11,8 @@ namespace CodeWalker
{
public long MaxMemoryUsage = 536870912; //512mb
public long CurrentMemoryUsage = 0;
public double CacheTime = 5.0; //seconds to keep something that's not used
public double CacheTime = 10.0; //seconds to keep something that's not used
public DateTime CurrentTime = DateTime.Now;
private LinkedList<TVal> loadedList = new LinkedList<TVal>();
private Dictionary<TKey, LinkedListNode<TVal>> loadedListDict = new Dictionary<TKey, LinkedListNode<TVal>>();
@ -33,6 +34,12 @@ namespace CodeWalker
CacheTime = cacheTime;
}
public void BeginFrame()
{
CurrentTime = DateTime.Now;
Compact();
}
public TVal TryGet(TKey key)
{
LinkedListNode<TVal> lln = null;
@ -40,7 +47,7 @@ namespace CodeWalker
{
loadedList.Remove(lln);
loadedList.AddLast(lln);
lln.Value.LastUseTime = DateTime.Now;
lln.Value.LastUseTime = CurrentTime;
}
return (lln != null) ? lln.Value : null;
}
@ -65,7 +72,7 @@ namespace CodeWalker
int iter = 0, maxiter = 2;
while (!CanAdd() && (iter<maxiter))
{
while ((!CanAdd()) && (oldlln != null) && ((DateTime.Now - oldlln.Value.LastUseTime).TotalSeconds > cachetime))
while ((!CanAdd()) && (oldlln != null) && ((CurrentTime - oldlln.Value.LastUseTime).TotalSeconds > cachetime))
{
Interlocked.Add(ref CurrentMemoryUsage, -oldlln.Value.MemoryUsage);
loadedListDict.Remove(oldlln.Value.Key);
@ -113,16 +120,33 @@ namespace CodeWalker
{
loadedListDict.Remove(key);
loadedList.Remove(n);
CurrentMemoryUsage -= n.Value.MemoryUsage;
Interlocked.Add(ref CurrentMemoryUsage, -n.Value.MemoryUsage);
}
}
public void Compact()
{
var oldlln = loadedList.First;
while (oldlln != null)
{
if ((CurrentTime - oldlln.Value.LastUseTime).TotalSeconds < CacheTime) break;
var nextln = oldlln.Next;
Interlocked.Add(ref CurrentMemoryUsage, -oldlln.Value.MemoryUsage);
loadedListDict.Remove(oldlln.Value.Key);
loadedList.Remove(oldlln); //gc should free up memory later..
oldlln.Value = null;
oldlln = nextln;
}
}
}
public abstract class Cacheable<TKey>
{
public TKey Key;
public DateTime LastUseTime = DateTime.Now;
public DateTime LastUseTime;
public long MemoryUsage;
}

View File

@ -165,6 +165,8 @@ namespace CodeWalker
{
if (FileCache.IsInited)
{
FileCache.BeginFrame();
bool fcItemsPending = FileCache.ContentThreadProc();
if (!fcItemsPending)

View File

@ -213,13 +213,14 @@ namespace CodeWalker.Peds
if (pauserendering) return;
GameFileCache.BeginFrame();
if (!Monitor.TryEnter(Renderer.RenderSyncRoot, 50))
{ return; } //couldn't get a lock, try again next time
UpdateControlInputs(elapsed);
//space.Update(elapsed);
Renderer.Update(elapsed, MouseLastPoint.X, MouseLastPoint.Y);

View File

@ -1652,6 +1652,23 @@ namespace CodeWalker.Rendering
for (int i = 0; i < ents.Count; i++) //make sure to remove the renderable references to avoid hogging memory
{
var ent = ents[i];
ent.LodManagerRenderable = null;
}
foreach (var ent in RequiredParents.Keys)
{
var pcnode = ent.LodManagerChildren?.First;
while (pcnode != null)//maybe can improve performance of this
{
var pcent = pcnode.Value;
pcent.LodManagerRenderable = null;
pcnode = pcnode.Next;
}
}
RenderWorldYmapExtras();
}
@ -3586,6 +3603,8 @@ namespace CodeWalker.Rendering
var ent = ymap.AllEntities[i];
RootEntities.Remove(ent);
ent.LodManagerChildren?.Clear();
ent.LodManagerChildren = null;
ent.LodManagerRenderable = null;
if ((ent.Parent != null) && (ent.Parent.Ymap != ymap))
{
ent.Parent.LodManagerRemoveChild(ent);

View File

@ -164,13 +164,14 @@ namespace CodeWalker.Vehicles
if (pauserendering) return;
GameFileCache.BeginFrame();
if (!Monitor.TryEnter(Renderer.RenderSyncRoot, 50))
{ return; } //couldn't get a lock, try again next time
UpdateControlInputs(elapsed);
//space.Update(elapsed);
Renderer.Update(elapsed, MouseLastPoint.X, MouseLastPoint.Y);

View File

@ -398,6 +398,8 @@ namespace CodeWalker
if (pauserendering) return;
GameFileCache.BeginFrame();
if (!Monitor.TryEnter(Renderer.RenderSyncRoot, 50))
{ return; } //couldn't get a lock, try again next time