Partial Fix for Memory issue - Limiting the number of ImageSources cached (#4433)

* reducing storage of images

* Added task.run

* cleaned up code and added comments

* Renamed variable

* refactored code

* Removed task.run because it was leading to race conditions in the concurrent dictionary and it was taking only upto 10 ms for reordering the dictionary

* Added comments and fixed variable name
This commit is contained in:
Alekhya 2020-06-26 10:20:35 -07:00 committed by GitHub
parent d2f1f67a22
commit 5745a984aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 4 deletions

View File

@ -2,6 +2,7 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Media;
namespace Wox.Infrastructure.Image
@ -9,10 +10,10 @@ namespace Wox.Infrastructure.Image
[Serializable]
public class ImageCache
{
private const int MaxCached = 5000;
private const int MaxCached = 50;
public ConcurrentDictionary<string, int> Usage = new ConcurrentDictionary<string, int>();
private readonly ConcurrentDictionary<string, ImageSource> _data = new ConcurrentDictionary<string, ImageSource>();
private const int permissibleFactor = 2;
public ImageSource this[string path]
{
@ -22,7 +23,29 @@ namespace Wox.Infrastructure.Image
var i = _data[path];
return i;
}
set { _data[path] = value; }
set
{
_data[path] = value;
// To prevent the dictionary from drastically increasing in size by caching images, the dictionary size is not allowed to grow more than the permissibleFactor * maxCached size
// This is done so that we don't constantly perform this resizing operation and also maintain the image cache size at the same time
if (_data.Count > permissibleFactor * MaxCached)
{
// This function resizes the Usage dictionary, taking the top 'maxCached' number of items and filtering the image icons that are not accessed frequently.
Cleanup();
// To delete the images from the data dictionary based on the resizing of the Usage Dictionary.
foreach (var key in _data.Keys)
{
int dictValue;
if (!Usage.TryGetValue(key, out dictValue))
{
ImageSource imgSource;
_data.TryRemove(key, out imgSource);
}
}
}
}
}
public void Cleanup()

View File

@ -185,9 +185,13 @@ namespace Wox.Infrastructure.Image
string hash = EnableImageHash ? _hashGenerator.GetHashFromImage(img) : null;
if (hash != null)
{
int ImageCacheValue;
if (GuidToKey.TryGetValue(hash, out string key))
{ // image already exists
img = ImageCache[key];
if(ImageCache.Usage.TryGetValue(path, out ImageCacheValue))
{
img = ImageCache[key];
}
}
else
{ // new guid