हम .NET का उपयोग कर एक वेब फार्म चला रहे हैं। प्रत्येक वेब सर्वर में इसकी स्मृति में स्थिर वस्तुओं की काफी मात्रा होती है। एक जनरल 2 कचरा संग्रह (जीसी) 10-20 सेकंड लेता है और यह हर 5 मिनट में चलता है। हम उसी समस्या में अधिक या कम भाग गए जो StackOverflow में भाग गया: http://samsaffron.com/archive/2011/10/28/in-managed-code-we-trust-our-recent-battles-with-the-net-garbage-collectorमिस्ड कचरा संग्रह अधिसूचनाएं
फिलहाल, हम कैश में ऑब्जेक्ट्स की संख्या को कम कर रहे हैं। हालांकि, इसमें समय लगता है।
उसी समय, हमने जीसी के पास आने के बारे में .NET में अधिसूचनाएं प्राप्त करने के लिए here दस्तावेज किए गए तरीकों को लागू किया। लक्ष्य जीसी के आने के बाद खेत में शामिल होने और जीसी खत्म होने के बाद इसे खेत में शामिल करने का लक्ष्य है। हालांकि, हमें केवल सभी जीसी के 0.7% के लिए अधिसूचना मिलती है। हम एक अधिकतम जनरेशन थ्रेसहोल्ड और bigObjectHeapThreshold 8 का उपयोग कर रहे हैं। हमने अन्य थ्रेसहोल्ड की कोशिश की, लेकिन मिस्ड जीसी की मात्रा में बदलाव नहीं आया।
हम समवर्ती सर्वर कचरा संग्रह (http://msdn.microsoft.com/en-us/library/ms229357.aspx) का उपयोग कर रहे हैं। जीसीलाटेंसी मोड इंटरएक्टिव है (http://msdn.microsoft.com/en-us/library/system.runtime.gclatencymode.aspx देखें)। यहां फिर से, हमने अन्य जीसी मोड (वर्कस्टेशन मोड, बैच इत्यादि) का उपयोग करने की कोशिश की। और फिर हमें अधिकांश जीसी के लिए अधिसूचना नहीं मिली।
क्या हम कुछ गलत कर रहे हैं, या क्या हर जीसी के लिए अधिसूचना प्राप्त करना असंभव है? हम अधिसूचनाओं की संख्या कैसे बढ़ा सकते हैं?
http://assets.red-gate.com/community/books/assets/Under_the_Hood_of_.NET_Management.pdf के अनुसार, शुरुआत में जीसी 2 जीबी हिट होने पर जीसी ट्रिगर होता है। हमारे पास बहुत सी रैम है, इसलिए यदि हम इस दहलीज को मैन्युअल रूप से उच्च स्तर पर सेट कर सकते हैं, तो इस सीमा तक पहुंचने में अधिक समय लगेगा और मेरी समझ में अधिसूचना प्राप्त करने में संभावना बढ़ेगी। क्या इस दहलीज को संशोधित करने का कोई तरीका है?
GC.RegisterForFullGCNotification(gcThreshold, gcThreshold);
// Start a thread using WaitForFullGCProc.
thWaitForFullGC = new Thread(WaitForFullGCProc);
thWaitForFullGC.Name = "HealthTestGCNotificationListenerThread (Threshold=" + gcThreshold + ")";
thWaitForFullGC.IsBackground = true;
WaitForFullGCProc():
इस कोड है कि पंजीकृत करता है और सूचनाओं को सुनता है
private void WaitForFullGCProc()
{
try
{
while (!gcAbort)
{
// Check for a notification of an approaching collection.
GCNotificationStatus s;
do
{
int timeOut = CheckForMissedGc() > 0 ? 5000 : (10 * 60 * 1000);
s = GC.WaitForFullGCApproach(timeOut);
if (this.GcState == GCState.InducedUnnotified)
{
// Set the GcState back to okay to prevent the message from staying in the ApplicationMonitoring.
this.GcState = GCState.Okay;
}
} while (s == GCNotificationStatus.Timeout);
if (s == GCNotificationStatus.Succeeded)
{
SetGcState(GCState.Approaching, "GC is approaching..");
gcApproachNotificationCount++;
}
else
{
...
}
Stopwatch stopwatch = Stopwatch.StartNew();
s = GC.WaitForFullGCComplete((int)PrewarnTime.TotalMilliseconds);
long elapsed = stopwatch.ElapsedMilliseconds;
if (s == GCNotificationStatus.Timeout)
{
if (this.ForceGCWhenApproaching && !this.IsInGc && !this.IsPeriodicGcApproaching)
{
this.IsInGc = true;
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, blocking: true);
GC.WaitForPendingFinalizers();
elapsed = stopwatch.ElapsedMilliseconds;
this.IsInGc = false;
}
}
}
gcAbort = false;
}
catch (Exception e)
{
}
}
साथ यह करने के लिए सदस्यता आप शायद कोड जहां आप रजिस्टर और जीसी सूचनाओं के लिए सुनने के बाद सकते हैं? – Alex
'जीसी। रजिस्ट्रारफॉरफुलजीसी नोटिफिकेशन (जीसी थ्रेसहोल्ड, जीसी थ्रेसहोल्ड); // WaitForFullGCProc का उपयोग करके थ्रेड प्रारंभ करें। thWaitForFullGC = नया थ्रेड (WaitForFullGCProc); thWaitForFullGC.Name = "HealthTestGCNotificationListenerThread (थ्रेसहोल्ड =" + gcThreshold + ")"; thWaitForFullGC।IsBackground = सच है; – kopernik