عدم التطابق في حجم الكائن الذي يتم إرجاعه بواسطة sos.dll وحجم العملية في الذاكرة

StackOverflow https://stackoverflow.com/questions/2316460

  •  22-09-2019
  •  | 
  •  

سؤال

لقد استخدمت الأمر sos التالي لتعداد كافة مثيلات نوع معين في تطبيق asp قيد التشغيل (مستضاف على جهاز يعمل بنظام التشغيل Windows xp بسعة 4 جيجابايت).

.foreach (obj { !dumpheap -type ::my type:: -short ::start of address space:: ::end of address space:: }) { !objsize ${obj} }.

يؤدي هذا إلى تعداد كافة الكائنات من النوع المحدد في gc gen2.

يبدو أن حجم الكائن في المتوسط ​​يبلغ حوالي 500 كيلو بايت ويوجد حوالي 2000 كائن.يضيف هذا وحده ما يصل إلى حوالي 1 جيجابايت من الذاكرة بينما تظهر ذاكرة عملية asp في مدير المهام حوالي 700 ميجابايت فقط.نقطة أخرى هي أنني لم أفكر في الكائنات المحملة الأخرى التي أستخدمها.

كما أن جميع الكائنات المذكورة أعلاه هي كائنات جذرية لن يتم جمع البيانات المهملة فيها.لست متأكدًا مما إذا كان هذا الأمر خاطئًا أو إذا كان هناك أي تفسير آخر لعدم التطابق في الحجم الذي يُرجعه sos وما يظهر في مدير المهام؟

شكرا لك مقدما،
بهارات ك.

هل كانت مفيدة؟

المحلول

!objsize يحسب حجم المثيل بما في ذلك جميع الكائنات المرجعية الخاصة به، لذلك إذا كان لديك أي كائنات تشترك في مراجع إلى كائنات أخرى، فسيتم حساب حجمها عدة مرات.ربما يكون المصدر الأكثر شيوعًا لهذا هو السلاسل، حيث يتم تضمين السلاسل الحرفية وبالتالي مشاركتها بين الكائنات التي تستخدم نفس النص الحرفي.ومع ذلك، قد يكون لديك أيضًا مجموعات تشير إلى نفس الكائنات.على أية حال، سيكون المجموع غير صحيح إلا إذا كانت الكائنات التي تم جردها لا تشترك في أي مراجع على الإطلاق.

النظر في هذا المثال

class SomeType {
    private readonly string Text;

    public SomeType(string text) {
        Text = text;
    }
}

وهذا الرمز

var st1 = new SomeType("this is a long string that will be stored only once due to interning");
var st2 = new SomeType("this is a long string that will be stored only once due to interning");

في ويندبغ

0:006> !dumpheap -type Some
 Address       MT     Size
00ceb44c 00b738a8       12     
00ceb458 00b738a8       12     

0:006> !objsize 00ceb44c
sizeof(00ceb44c) =          164 (        0xa4) bytes (TestApp.SomeType)
0:006> !objsize 00ceb458
sizeof(00ceb458) =          164 (        0xa4) bytes (TestApp.SomeType)

0:006> !DumpObj 00ceb44c
Name:        TestApp.SomeType
MethodTable: 00b738a8
EEClass:     00b714bc
Size:        12(0xc) bytes
File:        c:\dev2010\FSharpLib\TestApp\bin\Release\TestApp.exe
Fields:
      MT    Field   Offset                 Type VT     Attr    Value Name
79b9d2b8  4000001        4        System.String  0 instance 00ceb390 Text
0:006> !DumpObj 00ceb458
Name:        TestApp.SomeType
MethodTable: 00b738a8
EEClass:     00b714bc
Size:        12(0xc) bytes
File:        c:\dev2010\FSharpLib\TestApp\bin\Release\TestApp.exe
Fields:
      MT    Field   Offset                 Type VT     Attr    Value Name
79b9d2b8  4000001        4        System.String  0 instance 00ceb390 Text

كما ترون من إخراج !dumpobj, ، كلاهما يشتركان في نفس المرجع، لذلك إذا قمت بجمع الحجم كما تم الإبلاغ عنه بواسطة !objsize أعلاه، يتم حساب السلسلة مرتين.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top