1
0
forked from mirrors/0ad

Modify GC scheduling and reduce VFS cache size.

It seems like there is a memory leak if we haven't finished with the
marking phase of an incremental GC and SpiderMonkey has to trigger a
full GC because it runs out of memory. With this patch we stop trying to
make incremental GCs if we are above 1/2 of the runtime size and do Full
GCs instead. This should make such low memory conditions even less
likely than they were already after the previous patch. Also reduce the
maximum VFS cache size to 400 MB.
Refs #2808

This was SVN commit r15831.
This commit is contained in:
Yves
2014-10-04 00:43:04 +00:00
parent 9c4eb0295a
commit 5a985e18f4
2 changed files with 58 additions and 21 deletions
+1 -1
View File
@@ -358,7 +358,7 @@ static size_t ChooseCacheSize()
const ssize_t os = (ssize_t)OperatingSystemFootprint();
const ssize_t game = 300; // estimated working set
ssize_t cache = 500; // upper bound: total size of our data
ssize_t cache = 400; // upper bound: total size of our data
// the cache reserves contiguous address space, which is a precious
// resource on 32-bit systems, so don't use too much:
+57 -20
View File
@@ -139,7 +139,8 @@ public:
m_rooter(NULL),
m_LastGCBytes(0),
m_LastGCCheck(0.0f),
m_HeapGrowthBytesGCTrigger(heapGrowthBytesGCTrigger)
m_HeapGrowthBytesGCTrigger(heapGrowthBytesGCTrigger),
m_RuntimeSize(runtimeSize)
{
m_rt = JS_NewRuntime(runtimeSize, JS_USE_HELPER_THREADS);
@@ -161,11 +162,9 @@ public:
JS::SetGCSliceCallback(m_rt, GCSliceCallbackHook);
JS_SetGCParameter(m_rt, JSGC_MAX_MALLOC_BYTES, 384 * 1024 * 1024);
JS_SetGCParameter(m_rt, JSGC_MAX_BYTES, 384 * 1024 * 1024);
JS_SetGCParameter(m_rt, JSGC_MAX_MALLOC_BYTES, m_RuntimeSize);
JS_SetGCParameter(m_rt, JSGC_MAX_BYTES, m_RuntimeSize);
JS_SetGCParameter(m_rt, JSGC_MODE, JSGC_MODE_INCREMENTAL);
//JS_SetGCParameter(m_rt, JSGC_SLICE_TIME_BUDGET, 5);
JS_SetGCParameter(m_rt, JSGC_ALLOCATION_THRESHOLD, 256);
// The whole heap-growth mechanism seems to work only for non-incremental GCs.
// We disable it to make it more clear if full GCs happen triggered by this JSAPI internal mechanism.
@@ -177,6 +176,7 @@ public:
ENSURE(m_dummyContext);
}
#define GC_DEBUG_PRINT 0
void MaybeIncrementalGC(double delay)
{
PROFILE2("MaybeIncrementalGC");
@@ -201,30 +201,66 @@ public:
m_LastGCCheck = timer_Time();
int gcBytes = JS_GetGCParameter(m_rt, JSGC_BYTES);
//std::cout << "gcBytes: " << std::endl; // debugging
#if GC_DEBUG_PRINT
std::cout << "gcBytes: " << gcBytes / 1024 << " KB" << std::endl;
#endif
if (m_LastGCBytes > gcBytes || m_LastGCBytes == 0)
{
//printf("Setting m_LastGCBytes: %d \n", gcBytes); // debugging
#if GC_DEBUG_PRINT
printf("Setting m_LastGCBytes: %d KB \n", gcBytes / 1024);
#endif
m_LastGCBytes = gcBytes;
}
// Run an additional incremental GC slice if the currently running incremental GC isn't over yet
// ... or
// start a new incremental GC if the JS heap size has grown enough for a GC to make sense
if (JS::IsIncrementalGCInProgress(m_rt) || (gcBytes - m_LastGCBytes > m_HeapGrowthBytesGCTrigger))
{
// Use for debugging
/*if (JS::IsIncrementalGCInProgress(m_rt))
printf("Running incremental GC because an incremental cycle is in progress. \n");
{
#if GC_DEBUG_PRINT
if (JS::IsIncrementalGCInProgress(m_rt))
printf("An incremental GC cycle is in progress. \n");
else
printf("Running incremental GC because JSGC_BYTES - m_LastGCBytes > m_HeapGrowthBytesGCTrigger "
" ---- JSGC_BYTES: %d m_LastGCBytes: %d m_HeapGrowthBytesGCTrigger: %d ",
gcBytes,
m_LastGCBytes,
m_HeapGrowthBytesGCTrigger);
}*/
PrepareContextsForIncrementalGC();
JS::IncrementalGC(m_rt, JS::gcreason::REFRESH_FRAME, GCSliceTimeBudget);
printf("GC needed because JSGC_BYTES - m_LastGCBytes > m_HeapGrowthBytesGCTrigger \n"
" JSGC_BYTES: %d KB \n m_LastGCBytes: %d KB \n m_HeapGrowthBytesGCTrigger: %d KB \n",
gcBytes / 1024,
m_LastGCBytes / 1024,
m_HeapGrowthBytesGCTrigger / 1024);
#endif
// A hack to make sure we never exceed the runtime size because we can't collect the memory
// fast enough.
if(gcBytes > m_RuntimeSize / 2)
{
if (JS::IsIncrementalGCInProgress(m_rt))
{
#if GC_DEBUG_PRINT
printf("Finishing incremental GC because gcBytes > m_RuntimeSize / 2. \n");
#endif
PrepareContextsForIncrementalGC();
JS::FinishIncrementalGC(m_rt, JS::gcreason::REFRESH_FRAME);
}
else
{
#if GC_DEBUG_PRINT
printf("Running full GC because gcBytes > m_RuntimeSize / 2. \n");
#endif
JS_GC(m_rt);
}
}
else
{
#if GC_DEBUG_PRINT
if (!JS::IsIncrementalGCInProgress(m_rt))
printf("Starting incremental GC \n");
else
printf("Running incremental GC slice \n");
#endif
PrepareContextsForIncrementalGC();
JS::IncrementalGC(m_rt, JS::gcreason::REFRESH_FRAME, GCSliceTimeBudget);
}
m_LastGCBytes = gcBytes;
}
}
@@ -255,6 +291,7 @@ private:
// Workaround for: https://bugzilla.mozilla.org/show_bug.cgi?id=890243
JSContext* m_dummyContext;
int m_RuntimeSize;
int m_HeapGrowthBytesGCTrigger;
int m_LastGCBytes;
double m_LastGCCheck;