Bug 490384 - Only evict unused cache entries when under memory pressure. r=vlad a=sdwilsh for push into CLOSED TREE

Prior to thise, when we were under memory pressure, we would remove every
entry from the cache, even ones that were currently held in memory due to
their use on e.g. a web page. Now we only remove things from the cache that
will actually free up memory, further fixing bug 466586.
This commit is contained in:
Joe Drew 2009-05-07 16:55:06 -04:00
parent 6db0826e1c
commit c77ce2595e
2 changed files with 32 additions and 8 deletions

View File

@ -451,11 +451,10 @@ NS_IMETHODIMP
imgCacheObserver::Observe(nsISupports* aSubject, const char* aTopic, const PRUnichar* aSomeData)
{
if (strcmp(aTopic, "memory-pressure") == 0) {
mLoader.ClearCache(PR_FALSE);
mLoader.ClearCache(PR_TRUE);
mLoader.MinimizeCaches();
} else if (strcmp(aTopic, "chrome-flush-skin-caches") == 0 ||
strcmp(aTopic, "chrome-flush-caches") == 0) {
mLoader.ClearCache(PR_TRUE);
mLoader.ClearChromeImageCache();
}
return NS_OK;
}
@ -656,12 +655,18 @@ void imgLoader::Shutdown()
nsresult imgLoader::ClearChromeImageCache()
{
return EvictEntries(sChromeCache, sChromeCacheQueue);
return EvictEntries(sChromeCache);
}
nsresult imgLoader::ClearImageCache()
{
return EvictEntries(sCache, sCacheQueue);
return EvictEntries(sCache);
}
void imgLoader::MinimizeCaches()
{
EvictEntries(sCacheQueue);
EvictEntries(sChromeCacheQueue);
}
PRBool imgLoader::PutIntoCache(nsIURI *key, imgCacheEntry *entry)
@ -1106,9 +1111,9 @@ static PLDHashOperator EnumEvictEntries(const nsACString&,
return PL_DHASH_NEXT;
}
nsresult imgLoader::EvictEntries(imgCacheTable &aCacheToClear, imgCacheQueue &aQueueToClear)
nsresult imgLoader::EvictEntries(imgCacheTable &aCacheToClear)
{
LOG_STATIC_FUNC(gImgLog, "imgLoader::EvictEntries");
LOG_STATIC_FUNC(gImgLog, "imgLoader::EvictEntries table");
// We have to make a temporary, since RemoveFromCache removes the element
// from the queue, invalidating iterators.
@ -1122,6 +1127,23 @@ nsresult imgLoader::EvictEntries(imgCacheTable &aCacheToClear, imgCacheQueue &aQ
return NS_OK;
}
nsresult imgLoader::EvictEntries(imgCacheQueue &aQueueToClear)
{
LOG_STATIC_FUNC(gImgLog, "imgLoader::EvictEntries queue");
// We have to make a temporary, since RemoveFromCache removes the element
// from the queue, invalidating iterators.
nsTArray<nsRefPtr<imgCacheEntry> > entries(aQueueToClear.GetNumElements());
for (imgCacheQueue::const_iterator i = aQueueToClear.begin(); i != aQueueToClear.end(); ++i)
entries.AppendElement(*i);
for (PRUint32 i = 0; i < entries.Length(); ++i)
if (!RemoveFromCache(entries[i]))
return NS_ERROR_FAILURE;
return NS_OK;
}
#define LOAD_FLAGS_CACHE_MASK (nsIRequest::LOAD_BYPASS_CACHE | \
nsIRequest::LOAD_FROM_CACHE)

View File

@ -235,6 +235,7 @@ public:
static nsresult ClearChromeImageCache();
static nsresult ClearImageCache();
static void MinimizeCaches();
static nsresult InitCache();
@ -302,7 +303,8 @@ private: // methods
typedef nsRefPtrHashtable<nsCStringHashKey, imgCacheEntry> imgCacheTable;
static nsresult EvictEntries(imgCacheTable &aCacheToClear, imgCacheQueue &aQueueToClear);
static nsresult EvictEntries(imgCacheTable &aCacheToClear);
static nsresult EvictEntries(imgCacheQueue &aQueueToClear);
static imgCacheTable &GetCache(nsIURI *aURI);
static imgCacheQueue &GetCacheQueue(nsIURI *aURI);