سؤال

دعونا نقول كنت تريد أن تكتب عالية الأداء الأسلوب الذي يعالج مجموعة كبيرة من البيانات.لماذا لا يكون للمطورين القدرة على تشغيل يدوي إدارة الذاكرة بدلا من إجبارهم على الانتقال إلى C أو C++?

void Process()
{
    unmanaged
    {
        Byte[] buffer;
        while (true)
        {
            buffer = new Byte[1024000000];

            // process

            delete buffer;
        } 
    }   
}
هل كانت مفيدة؟

المحلول

لأن السماح لك بحذف كتلة الذاكرة يدويا أثناء وجود إشارات إليها (ويمكن أن يكون وقت التشغيل أي طريقة لمعرفة ذلك دون القيام دورة GC) بإنتاج مؤشرات تتدلى، وبالتالي كسر سلامة الذاكرة. وبعد لغات لغات هي عموما آمنة في الذاكرة حسب التصميم.

مما قال، في C #، على وجه الخصوص، يمكنك أن تفعل ما تريد بالفعل:

void Process()
{
    unsafe
    {
        byte* buffer;
        while (true)
        {
            buffer = Marshal.AllocHGlobal(1024000000);

            // process

            Marshal.FreeHGlobal(buffer);
        } 
    }   
}

لاحظ أنه، كما هو الحال في C / C ++، لديك حساب مؤشر كامل لأنواع المؤشر الخام في C # - هكذا buffer[i] أو buffer+i هي تعبيرات صالحة.

نصائح أخرى

إذا كنت تحتاج إلى أداء عالي و تحكم مفصل, ربما يجب عليك أن تكتب ما تفعله في C أو C++.ليس كل اللغات هي جيدة لجميع الأشياء.

التعديل لإضافة:لغة واحدة لن تكون جيدة لجميع الأشياء.إذا كنت تضيف ما يصل جميع الميزات المفيدة في كل الخير لغات البرمجة, وأنت تسير في الحصول على فوضى كبيرة حقا ، أسوأ بكثير من C++, حتى إذا كان يمكنك تجنب التناقض.

ميزات ليست مجانية.إذا كانت اللغة لديه ميزة ، الناس من المحتمل أن استخدامه.أنت لن تكون قادرة على تعلم C# جيدا بما فيه الكفاية دون تعلم C# دليل إدارة الذاكرة الروتينية.مترجم فرق تنوي تنفيذ ذلك على حساب الأخرى مترجم الميزات التي هي مفيدة.اللغة المرجح أن تصبح من الصعب تحليل مثل C أو C++, و هذا يؤدي إلى بطء تجميع.(C++ الرجل, أنا دائما مندهش عند ترجمة واحد من C# المشاريع.تجميع يبدو بشكل فوري تقريبا.)

ملامح صراع مع بعضها البعض ، وأحيانا بطرق غير متوقعة.C90 لا تستطيع أن تفعل وكذلك Fortran في مصفوفة الحسابات لأنه احتمال أن ج مؤشرات مستعارة يمنع بعض التحسينات.إذا كنت تسمح مؤشر الحساب في اللغة ، عليك أن تقبل عواقبه.

أنت تقترح C# امتداد للسماح دليل إدارة الذاكرة, و في حالات قليلة قد تكون مفيدة.هذا يعني أن الذاكرة قد تخصص في طرق منفصلة ، يجب أن يكون هناك طريقة لمعرفة يدويا تمكن الذاكرة من تمكنت تلقائيا الذاكرة.فجأة, لقد معقدة إدارة الذاكرة ، هناك أكثر من فرصة مبرمج المسمار ، إدارة الذاكرة في حد ذاته هو أكثر تعقيدا.أنت تكتسب القليل من الأداء الذي يهم في حالات قليلة في مقابل المزيد من المضاعفات و أبطأ إدارة الذاكرة في جميع الحالات.

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

في المثال الذي نشرته، لماذا ليس فقط محو المخزن المؤقت وإعادة استخدامه؟

يعد جامع القمامة .NET جيدة جدا في العمل خارج الكائنات غير المرجعية بعد الآن وتحرير الذاكرة المرتبطة في الوقت المناسب. في الواقع، يحتوي جامع القمامة على كومة خاصة (كائن الكائن الكبير) الذي يضع فيه كائنات كبيرة مثل هذا، والتي تم تحسينها للتعامل معها.

علاوة على ذلك، لا يسمح بإطلاق سراح الإشارات المراد تحريرها بشكل صريح مضيفا كاملا من الأخطاء مع تسرب الذاكرة والمؤشرات المتدلية، يؤدي ذلك إلى رمز أكثر أمانا.

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

نفس السبب لن يسمح لك معظم النواة بجدولة المواضيع الخاصة بك. لأن 99.99 +٪ من الوقت لا تحتاج حقا، وفضح هذه الوظيفة، فستفعلك بقية الوقت فقط للقيام بشيء يمكن أن يكون غبيا / خطيرا.

إذا كنت بحاجة حقا إلى التحكم في ذاكرة الحبوب الجميلة، فاكتب هذا القسم من التعليمات البرمجية في شيء آخر.

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