- بواسطة x32x01 ||
ازاي طريقة تخزين الذاكرة في .NET اتغيّرت بالكامل؟ 

لو انت مبرمج .NET أو شغال بـ C#، أكيد سمعت الجملة اللي كل الناس كانت بترددها سنين طويلة:
"الـ struct بيتخزن في Stack والـ class بيتخزن في Heap."
الكلام ده كان صح زمان… لكن كان مناسب للإصدارات القديمة من .NET.
إنما من بعد .NET 10 ومع إصدار C# 14، مايكروسوفت قلبت المعادلة وعملت تطوير ضخم في طريقة تعامل الـ runtime مع الذاكرة، وخلت العملية أذكى وأسرع بفرق كبير.
دلوقتي تخزين الذاكرة بقى بيعتمد على سلوك الكائن (Object Behavior) مش نوعه بس زي زمان.
يعني ببساطة:
ممكن الـ runtime يخزن class على الـ Stack وليس الـ Heap — وده كان مستحيل قبل النسخة الجديدة!

في البوست ده هفهمك الموضوع بشكل بسيط وسهل، مع أمثلة كود واضحة، وهنشوف ليه التغيير ده يعتبر نقلة كبيرة في أداء تطبيقات .NET.
يلا نبدأ
ليه أصلاً كان في فصل بين Stack و Heap؟
قبل ما نفهم التغيير الجديد، لازم نفتكر الأساس:
علشان كده زمان كانوا بيقولوا:
والقانون كان بسيط وواضح…
لكن المشكلة إن القاعدة دي كانت بتضيع فرص كبيرة لتحسين الأداء.
ليه؟
لإن فيه حالات كتير الـ class بيكون عمره قصير جدًا، ومش محتاج كل التعقيد بتاع الـ Heap.
التطور الجديد في .NET 10: تخزين أذكى
مايكروسوفت قدمت ميزة عبقرية اسمها:
Escape Analysis
والفكرة بسيطة جدًا:
الـ runtime بقى بيحلّل الكائن وبيسأل نفسه:
"هل الكائن ده هيخرج بره الـ scope؟
ولا هيفضل جوّاه ومش محتاج يعيش مدة طويلة؟"
لو الإجابة: لأ، مش هيهرب → يتخزن على Stack حتى لو كان class
لو الإجابة: أيوه، هيهرب → يتحط على Heap زي زمان.
أمثلة كود توضح الفكرة
في الإصدارات الجديدة:
الكائن p مش بيخرج بره الدالة Test، فـ runtime بيخزّنه على Stack.
ده معناه:
هنا الـ runtime هيقول:
“لحظة… الكائن هيتخزن في متغير عام (global) يعني عمره طويل.”
وبالتالي لازم يتخزن على Heap.
ليه التغيير ده مهم جدًا لمبرمجين .NET؟
فكل ما الكائنات تبقى أقرب للـ Stack، التطبيق يبقى أسرع.
دلوقتي معظم الكائنات الصغيرة مش هتوصله أصلاً.
محتاج تتجنب الـ class وتستخدم struct علشان الأداء؟
كل ده مش ضروري دلوقتي.
الـ runtime بقى يعمل الشغل لوحده
مثال عملي يوضح الفرق قبل وبعد
خلينا نشوف سيناريو بسيط:
هل لازم أغيّر طريقة كتابتي للكود؟
الإجابة: لأ.
الميزة شغالة تلقائي…
انت بس اكتب الكود الطبيعي بتاعك، و .NET 10 هيعرف الأنسب.
لكن لو عايز تستفيد أكتر:
هل ده معناه إن struct بقي بلا فايدة؟
لأ طبعًا.
الـ struct لسه ليه استخدامات مهمة جدًا، خصوصًا في:
الخلاصة
التغيير اللي حصل في .NET 10 يعتبر أكبر قفزة في إدارة الذاكرة من أيام إصدار .NET Core.
دلوقتي:
وبصراحة… التطور ده بيأكد إن C# ولسه واحدة من أقوى لغات البرمجة، ومايكروسوفت لسه بتطوّر فيها بشكل رهيب.
لو انت مبرمج .NET أو شغال بـ C#، أكيد سمعت الجملة اللي كل الناس كانت بترددها سنين طويلة:
"الـ struct بيتخزن في Stack والـ class بيتخزن في Heap."
الكلام ده كان صح زمان… لكن كان مناسب للإصدارات القديمة من .NET.
إنما من بعد .NET 10 ومع إصدار C# 14، مايكروسوفت قلبت المعادلة وعملت تطوير ضخم في طريقة تعامل الـ runtime مع الذاكرة، وخلت العملية أذكى وأسرع بفرق كبير.
دلوقتي تخزين الذاكرة بقى بيعتمد على سلوك الكائن (Object Behavior) مش نوعه بس زي زمان.
يعني ببساطة:
ممكن الـ runtime يخزن class على الـ Stack وليس الـ Heap — وده كان مستحيل قبل النسخة الجديدة!
في البوست ده هفهمك الموضوع بشكل بسيط وسهل، مع أمثلة كود واضحة، وهنشوف ليه التغيير ده يعتبر نقلة كبيرة في أداء تطبيقات .NET.
يلا نبدأ
ليه أصلاً كان في فصل بين Stack و Heap؟
قبل ما نفهم التغيير الجديد، لازم نفتكر الأساس:- Stack: سريع جدًا، مخصص لتخزين البيانات اللي عمرها قصير وبتخلص أول ما الـ scope يخلص.
- Heap: أبطأ شوية، مخصص للكائنات اللي عمرها أطول وبتحتاج Garbage Collector يمسحها.
علشان كده زمان كانوا بيقولوا:
- الـ struct قيمة Value Type → يتخزن في Stack
- الـ class كائن Reference Type → يتخزن في Heap
والقانون كان بسيط وواضح…
لكن المشكلة إن القاعدة دي كانت بتضيع فرص كبيرة لتحسين الأداء.
ليه؟
لإن فيه حالات كتير الـ class بيكون عمره قصير جدًا، ومش محتاج كل التعقيد بتاع الـ Heap.
التطور الجديد في .NET 10: تخزين أذكى 
مايكروسوفت قدمت ميزة عبقرية اسمها:Escape Analysis
والفكرة بسيطة جدًا:
الـ runtime بقى بيحلّل الكائن وبيسأل نفسه:
"هل الكائن ده هيخرج بره الـ scope؟
ولا هيفضل جوّاه ومش محتاج يعيش مدة طويلة؟"
لو الإجابة: لأ، مش هيهرب → يتخزن على Stack حتى لو كان class
لو الإجابة: أيوه، هيهرب → يتحط على Heap زي زمان.
أمثلة كود توضح الفكرة 
مثال 1: class بيتخزن على الـ Stack لأن عمره قصير
C#:
class Person
{
public string Name;
}
void Test()
{
var p = new Person();
p.Name = "Mostafa";
Console.WriteLine(p.Name);
} في الإصدارات الجديدة:
الكائن p مش بيخرج بره الدالة Test، فـ runtime بيخزّنه على Stack.
ده معناه:
- سرعة أعلى
- ضغط أقل على الـ Heap
- تقليل عمل Garbage Collector
مثال 2: class لازم يروح Heap لأنه بيهرب من النطاق
C#:
Person personGlobal;
void Test()
{
personGlobal = new Person();
} هنا الـ runtime هيقول:
“لحظة… الكائن هيتخزن في متغير عام (global) يعني عمره طويل.”
وبالتالي لازم يتخزن على Heap.
ليه التغيير ده مهم جدًا لمبرمجين .NET؟
1. أداء أعلى بنسبة كبيرة
الـ Stack أسرع من الـ Heap بكتير…فكل ما الكائنات تبقى أقرب للـ Stack، التطبيق يبقى أسرع.
2. تقليل ضغط Garbage Collector
GC كان بياخد وقت ومجهود كل ما Heap يكبر.دلوقتي معظم الكائنات الصغيرة مش هتوصله أصلاً.
3. كود أنضف من غير ما تعمل حاجة
محتاج تعمل refactoring؟محتاج تتجنب الـ class وتستخدم struct علشان الأداء؟
كل ده مش ضروري دلوقتي.
الـ runtime بقى يعمل الشغل لوحده
4. التطبيقات الثقيلة بقت أسرع
زي:- تطبيقات الويب ASP.NET
- الألعاب
- معالجة البيانات
- الخدمات اللي فيها طلبات كتير (microservices)
مثال عملي يوضح الفرق قبل وبعد
خلينا نشوف سيناريو بسيط: C#:
class Order
{
public int Id;
public double Total;
}
void Process()
{
for (int i = 0; i < 100000; i++)
{
var o = new Order { Id = i, Total = 50.5 };
}
} زمان:
- الـ 100 ألف object كانوا بيتخلقوا على Heap
- Garbage Collector كان يضطر يمسحهم
- الأداء كان ينزل
دلوقتي:
- الكائنات دي قصيرة العمر
- runtime بيحطها على Stack
- مفيش GC
- الأداء بيطير


هل لازم أغيّر طريقة كتابتي للكود؟
الإجابة: لأ.الميزة شغالة تلقائي…
انت بس اكتب الكود الطبيعي بتاعك، و .NET 10 هيعرف الأنسب.
لكن لو عايز تستفيد أكتر:
نصايح بسيطة:
- خليك مستمر في عدم تخزين object طويل العمر بدون سبب
- استخدم local variables قدر المستطاع
- تجنب نقل الكائنات لحقول (fields) إلا لو محتاج فعلاً
- بعد تحديث المشروع لـ .NET 10 هتحس الفرق في الأداء من غير ما تعمل حاجة
هل ده معناه إن struct بقي بلا فايدة؟
لأ طبعًا.الـ struct لسه ليه استخدامات مهمة جدًا، خصوصًا في:
- الألعاب
- المعالجة الرسومية
- الكائنات اللي حجمها صغير جدًا
- الـ Span والأنواع الجديدة
الخلاصة
التغيير اللي حصل في .NET 10 يعتبر أكبر قفزة في إدارة الذاكرة من أيام إصدار .NET Core.دلوقتي:
- الـ class ممكن يعيش على Stack

- الأداء أعلى بفرق كبير
- الـ runtime أذكى
- الكود أنضف وأسهل
- مفيش ضغط على Garbage Collector
- وده كله من غير ما تلمس سطر واحد في الكود بتاعك
وبصراحة… التطور ده بيأكد إن C# ولسه واحدة من أقوى لغات البرمجة، ومايكروسوفت لسه بتطوّر فيها بشكل رهيب.