تعدد. نموذج ذاكرة جافا (الجزء 2)

مرحبا هبر! أقدم انتباهكم إلى ترجمة الجزء الثاني من مقالة "نموذج ذاكرة جافا" بقلم جاكوب جينكوف. الجزء الأول هنا .



هندسة أجهزة الذاكرة



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



فيما يلي رسم تخطيطي مبسط لهندسة الأجهزة في الكمبيوتر الحديث:



غالبًا ما يحتوي الكمبيوتر الحديث على معالجين أو أكثر. قد تحتوي بعض هذه المعالجات أيضًا على نوى متعددة. على أجهزة الكمبيوتر هذه ، يمكن تشغيل عدة خيوط في وقت واحد. كل معالج (ملاحظة المترجم - من الآن فصاعدًا ، ربما يعني المؤلف نواة معالج أو معالج أحادي النواة بواسطة معالج)قادر على تشغيل موضوع واحد في أي وقت. هذا يعني أنه إذا كان تطبيق Java الخاص بك متعدد مؤشرات الترابط ، فيمكن تشغيل خيط واحد داخل برنامجك في وقت واحد لكل معالج.



يحتوي كل معالج على مجموعة من السجلات الموجودة أساسًا في ذاكرته. يمكنه إجراء عمليات على البيانات الموجودة في السجلات بشكل أسرع بكثير من البيانات الموجودة في الذاكرة الرئيسية للكمبيوتر (RAM). وذلك لأن المعالج يمكنه الوصول إلى هذه السجلات بشكل أسرع.



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



يحتوي الكمبيوتر أيضًا على مساحة من الذاكرة الرئيسية (RAM). يمكن لجميع المعالجات الوصول إلى الذاكرة الرئيسية. عادة ما تكون مساحة الذاكرة الرئيسية أكبر بكثير من ذاكرة التخزين المؤقت للمعالج.



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



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



الجمع بين نموذج ذاكرة Java وبنية ذاكرة الأجهزة



كما ذكرنا ، يختلف طراز ذاكرة Java وبنية أجهزة الذاكرة. لا تميز بنية الأجهزة بين مكدس مؤشر الترابط وكومة. على الأجهزة ، تكون مكدس الخيط والكومة في الذاكرة الرئيسية. يمكن أن توجد أحيانًا أجزاء من الحزم وأكوام الخيط في ذاكرات التخزين المؤقت والسجلات الداخلية لوحدة المعالجة المركزية. يظهر هذا في الرسم التخطيطي:



عندما يمكن تخزين الكائنات والمتغيرات في مناطق مختلفة من ذاكرة الكمبيوتر ، يمكن أن تنشأ بعض المشاكل. هناك نوعان رئيسيان:

• رؤية التغييرات التي تم إجراؤها بواسطة سلسلة الرسائل على المتغيرات المشتركة.

• ظروف العرق عند قراءة وفحص وكتابة المتغيرات المشتركة.

سيتم شرح كل من هذه المشاكل في الأقسام التالية.



رؤية الكائن المشترك



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



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



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



لحل هذه المشكلة ، يمكنك استخدامها volatileعند التصريح عن متغير. يمكنه ضمان قراءة متغير معين مباشرة من الذاكرة الرئيسية وإعادة كتابته دائمًا إلى الذاكرة الرئيسية عند التحديث.



حالة السباق



في حالة مشاركة اثنين أو أكثر من مؤشرات الترابط في نفس الكائن وأكثر من متغيرات تحديث مؤشر ترابط في ذلك الكائن المشترك ، قد تحدث حالة سباق .



تخيل أن الخيط A يقرأ متغير countكائن مشترك في ذاكرة التخزين المؤقت للمعالج. تخيل أيضًا أن الخيط B يقوم بنفس الشيء ، ولكن مع ذاكرة تخزين مؤقت لمعالج مختلف. الآن الخيط A يضيف 1 إلى قيمة المتغير count، والخيط B يفعل الشيء نفسه. الآن تمت var1زيادته مرتين - بشكل منفصل ، +1 في ذاكرة التخزين المؤقت لكل معالج.



إذا تم إجراء هذه الزيادات بالتسلسل ، countفسيتم مضاعفة المتغير وإعادة كتابته إلى الذاكرة الرئيسية + 2.

ومع ذلك ، تم إجراء الزيادتين في وقت واحد دون مزامنة مناسبة. بغض النظر عن أي مؤشر ترابط (A أو B) يكتب نسخته المحدثة countفي الذاكرة الرئيسية ، فإن القيمة الجديدة ستكون 1 فقط أكثر من القيمة الأصلية ، على الرغم من زيادتين.



يوضح هذا الرسم البياني حدوث مشكلة حالة السباق الموضحة أعلاه:



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



All Articles