مقدمة من أكاديمية حسوب
دورة تطوير التطبيقات باستخدام لغة JavaScript
في هذه الدورة ستتعلم لغة جافا سكريبت, استخدام مكتبة React.js, بناء API الموقع بواسطة Node.js, تطوير تطبيق جوال باستخدام React Native, و في نهاية الدورة ستتعلم تطوير تطبيق محادثة شبيه بتطبيق WhatsApp.
دورة تطوير واجهات المستخدم
في هذه الدورة ستتعلم لغة HTML و لغة CSS و لغة JavaScript. من ناحية التطبيق العملي ستتعلم طريقة بناء واجهة متجر إلكتروني مكون من ست صفحات, تحويل خمسة تصاميم PSD إلى صفحات ويب, بناء واجهة مستخدم تشبه موقع يوتيوب, بناء لوحة تحكم إحترافية.
دورة تطوير تطبيقات الجوال باستخدام تقنيات الويب
في هذه الدورة ستتعلم أساسيات منصة كوردوفا و كيف تستخدمها لتطوير تطبيقات متعددة المنصات, بناء تطبيق لموقع Wordpress, تطوير تطبيق قائمة مهام, تطوير تطبيق حالة الطقس, تطوير تطبيق لمطعم باستخدام إطار العمل Ionic 4.
دورة تطوير تطبيقات الويب باستخدام لغة PHP
في هذه الدورة ستتعلم لغة PHP من الصفر, استخدام إطار العمل Laravel بشرح مفصّل و عملي, كيفية تطوير شبكة اجتماعية تشبه Instagram, بناء API لتطبيق جوال وفق أسلوب RESTful, تطوير موقع إعلانات مبوبة, تطوير نظام إدارة محتوى CMS كامل.
دورة تطوير تطبيقات الويب باستخدام لغة Ruby
في هذه الدورة ستتعلم البرمجة بلغة Ruby إنطلاقاً من أبسط المفاهيم وحتى بناء تطبيق حقيقي, إستخدام إطار العمل Ruby on Rails بشرح مفصّل و عملي, بناء تطبيق حقيقي عبارة عن شبكة اجتماعية تشبه تويتر, تطوير مجتمع الكتروني يشبه حسوب I/O.
دورة علوم الحاسوب
هذه الدورة معدة لتكون مدخل لعلوم الحاسوب و لغات البرمجة حيث ستتعرف فيها على أنظمة التشغيل و ستتعمق في نظام لينكس و في كيفية التعامل معه من خلال موجه الأوامر, بالإضافة إلى قواعد البيانات و أساسيات الشبكات و الخوادم و مبادئ الحماية والأمان في الويب.

منظف الذاكرة في جافا Garbage Collector

تمتلك لغات البرمجة القديمة أوامر خاصة لإضافة وإزالة البيانات من الذاكرة العشوائية (RAM), ويكون المبرمج هو المسؤول عن إزالة البيانات التي لم يعد يحتاجها, لكن غالباً ما تكون هذه العملية متكررة و لا تحمل قيمة كبيرة فيهملها المبرمج وينتهي الأمر بإمتلاء الذاكرة.

لذلك توفر لغات البرمجة الحديثة طرقاً لإزالة البيانات التي لن يستخدمها البرنامج مجدداً بشكل تلقائي و بدون تدخل المبرمج. توفر جافا منظف الذاكرة أو جامع القمامة (Garbage Collector) والذي يكون مسؤولاً عن هذه العملية.

ما هو جامع القمامة وكيف يعمل وكيف نستفيد منه لأقصى حد؟
جامع القمامة هو برنامج موجود ضمن آلة جافا الافتراضية (JVM) يقوم بتنظيف الكومة (Heap), و الكومة هي مساحة يتم تخزين الكائنات التي ينشئها البرنامج فيها.

صورة توضح أجزاء Hotspot JVM, ويوجد جامع القمامة في Execution Engine

عند تشغيل آلة جافا الإفتراضية يتم تحديد مساحة الكومة التي يستطيع البرنامج إستغلالها, لكن عندما يقوم البرنامج بالإقتراب من ملء الكومة ينشط جامع القمامة ليرى إن كان يستطيع مسح الكائنات التي لم تعد تستخدم, ويستطيع جامع القمامة تمييز هذه الكائنات عندما لا تعود أي Thread تمتلك مرجعاً Reference لذلك الكائن, وهكذا يستحيل على أي Thread إستخدام ذلك الكائن في المستقبل. عندما يقرر جامع القمامة أنه سيحذف كائناً من الكومة سيقوم بتنفيذ الدالة finalize() على ذلك الكائن, و هذه الدالة موجودة في الكلاس Object مما يعني أنها مورثة لجميع الكائنات, ويفترض عند بناء أي صف أن تقوم بكتابة الأوامر التي يجب تنفيذها قبل حذف الكائن مثل إغلاق قنوات اتصال معينة IO Stream.

دعونا نجرب الكود التالي ونرى النتيجة.

public class test {
    public test() {
        System.out.println("constructing");
    }

    public static void main(String[] args) {
        new Thread() {
            public void run() {
                while (true) {
                    System.out.println(Runtime.getRuntime().totalMemory() / (1024.0f * 1024.0f) +"MB");
                }
            }
        }.start();
        while(true){
            new test();
        }
    }

    @Override protected void finalize() throws Throwable {
        System.out.println("finalizing");
    }
}

سنحصل على النتيجة التالية عند التشغيل.

constructing{73099}
61.5MB
finalizing

كما رأينا في هذه النتيجة الملخصة بعد طباعة الكلمة constructing 37099 مرة رأينا أول كلمة finalizing, وإستخدمنا الدالة ()Runtime.getRuntime().totalMemory لمعرفة المساحة التي تستهلكها JRE من الذاكرة العشوائية, ومن خلال أداة VisualVM إستطعنا الحصول على الصورة التالية.

من تحليل الشكل للكومة يمكننا ملاحظة أن المساحة المستخدمة تزداد إلى مرحلة تقترب فيها من 25MB وبعدها يتحفز جامع القمامة تلقائياً (ويدل على ذلك إرتفاع الخط الأزرق في الرسم البياني في الأعلى على اليسار) ليمسح الكائنات التي لن تستخدم في المستقبل, مما يفسر الإنخفاضات بعد نقاط الذروة.

 

إذاً لنجرب الآن محاولة تحفيز جامع القمامة من كود الجافا عبر إستدعاء الدالة System.gc();

public class test {
    public test() {
        System.out.println("constructoring");
    }

    public static void main(String[] args) {
        new Thread() {
            public void run() {
                while (true) {
                    try {
                            System.out.println(Runtime.getRuntime().totalMemory() / (1024.0f * 1024.0f) +"MB");
                            System.gc();
                            Thread.sleep(2000);
                    } catch (InterruptedException ex) {break;}
                }
            }
        }.start();
        while(true){
            new test();
        }
    }

    @Override
    protected void finalize() throws Throwable {
        System.out.println("finalizing");
    }
}

سنحصل على النتيجة التالية عند التشغيل.

constructoring{175}
61.5MB
finalizing

يمكننا ملاحظة فرق شاسع بين هذا المثال والمثال السابق في أول ظهور للكلمة finalizing, أما الرسم البياني فكان كالتالي.

من جهة كانت أكبر مساحة مستهلكة من الذاكرة في هذا المثال 5MB أما في المثال السابق كانت 25MB, ومن جهة أخرى كان أقصى استهلاك للمعالج 15% أما في المثال السابق فكان 7%, وتفسير ذلك أن عملية تحفيز جامع القمامة للبدء بالبحث داخل الكومة عن كائنات لإزالتها هي عملية مكلفة وتنفيذها بشكل دوري هو أمر غير مجدٍ.

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

import java.util.ArrayList;

public class test {
    private static ArrayList list = new ArrayList();
    public static void main(String[] args) {
        new Thread() {
            public void run() {
                while (true) {
                    System.out.println(Runtime.getRuntime().totalMemory() / (1024.0f * 1024.0f) +"MB");
                }
            }
        }.start();
        while(true){
            list.add("!@#$%^&*()1234567890qwertyuiop[]asdfghjkl;'zxcvbnm,./QWERTYUIOPASDFGHJKLZXCVBNM");
        }
    }
}

سنحصل على النتيجة التالية عند التشغيل.

61.5MB{50}
120.5MB{50}
173.5MB{50}
253.0MB{50}
372.0MB{50}
259.5MB{50}
438.0MB{50}
684.0MB{50}
		Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at
		java.util.Arrays.copyOf(Arrays.java:3181) at
		java.util.ArrayList.grow(ArrayList.java:261) at 
		java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:235) at 
		java.util.ArrayList.ensureCapacityInternal(ArrayList.java:227) at 
		org.rami.io.test.main(685.5MB test.java:36)
685.5MB{50}

نستطيع أن نرى من خلال هذا الكود أن جميع النصوص String التي تم توليدها قد تم حفظها في القائمة list, ولأن هذه القائمة تمتلك مرجعاً لكل النصوص المخزنة بداخلها فلا يستطيع جامع القمامة إزالتها من الذاكرة العشوائية, ولذلك قامت JRE بزيادة مساحة الكومة حتى أطلقت في النهاية الخطأ OutOfMemoryError معلنة أنها لا تملك مساحة أكبر لتخزين الكائنات في الكومة وأنها لا تستطيع زيادة مساحة الكومة أكثر من ذلك, وكان الرسم البياني كالتالي.

تمتلك كل JRE قيم لأعلى وأقل مساحة ممكنة للكومة, وفي حال تطويرك لبرنامج يستهلك مساحة كبيرة من الذاكرة العشوائية فيجب عليك تمرير معامل Xmx يحوي على أكبر مساحة مسموح للبرنامج بإستهلاكها من الذاكرة العشوائية عند تشغيل ملف JAR, وهذا الأمر في Windows CMD سيقوم بتشغيل ملف test.jar مع السماح له بإستهلاك 1GB من الذاكرة العشوائية.

java -Xmx1g -jar test.jar
نبّهني عن
guest
8 تعليقات
الآراء المضمنة
شاهد جميع التعليقات
محمد العلوش
1 سنة سابقاً

جزاك الله كل خير

محمد هرموش
المدير
1 سنة سابقاً

شرح أكثر من راااائع.. شكراً

maher
maher
1 سنة سابقاً

بالتوفيق شرح رائع 🌷🌷

ٍkon19
ٍkon19
1 سنة سابقاً

شكرا جزيلا للشرح اخ رامي

waleed smadi
waleed smadi
1 سنة سابقاً

هل المقصود من المقال ان عدم استخدام دالة جامع القمامة امر غير مجدي وان تركه للجي في ام هو الأفضل ؟

وشكرا على الشرح اخي . يعطيك العافية

معاذ
معاذ
5 شهور سابقاً

السلام عليكم
سؤال محتاج إجابة اذا تكرمتم
انا انشأت في هذا الكلاس عداد counter يعد كل object انشئ في الmain method وعند ازالة اي اوبجكت باعطاءه قيمة null واستدعاء ()system .gc بدي ال counter ينقص قيمة كل object أنا حذفته من الذاكرة
استدعيت ()finalyze وحطيت فيها counter–
ضلت قيمة counter ثابتة 5 كيف بدي اخلي قيمة counter تنقص ١ عند كل ازالة ل object
اي حدا عندو معلومة ياريت يفيدنا
وكل الشكر

جميع الحقوق محفوظة للموقع   ٢٠٢٠ - ٢٠١٤ ©
DMCA.com Protection Status

محتوى الموقع يخضع لرخصة (CC BY-NC-ND 4.0) التي لا تسمح باستخدام الشروحات لأغراض تجارية, إجراء تعديل عليها و نشرها في موقع آخر, وضع الشروحات في تطبيق أو في كتاب إلا في حال أخذ موافقة صريحة من إدارة الموقع.

© 2020 Harmash. All Content is licensed under CC BY-NC-ND 4.0 unless mentioned otherwise.