مقدمة: لماذا تحليل كود Java؟
\n\nالتطوير بلغة Java لا يقتصر على كتابة كود صحيح فحسب، بل يشمل أيضًا إنشاء تطبيقات سريعة وقابلة للتوسع. حتى النظام المصمم بشكل مثالي قد يصبح بطيئًا بسبب سطر واحد غير مثالي. كيف تجد هذا "عنق الزجاجة"؟ الإجابة هي التحليل.
\n\nالتحليل هو عملية جمع بيانات حول أداء التطبيق: وقت تنفيذ الدوال، استخدام الذاكرة، الخيوط، وحمل المعالج. بدونها، يتحول التحسين إلى تخمين. في هذه المقالة، سنستعرض أمثلة عملية لتحليل كود Java، ونتعلم تفسير النتائج وإيجاد نقاط الاختناق.
\n\nسننظر في أداتين شائعتين: VisualVM (مجاني، مدمج في JDK) و JProfiler (تجاري ولكنه قوي). جميع الأمثلة ستكون بكود حقيقي.
\n\nالجزء الرئيسي: ممارسة التحليل
\n\n1. إعداد البيئة وتشغيل المحلل
\n\nأولاً، تأكد من تثبيت JDK (الإصدار 8 أو أعلى). يأتي VisualVM مع JDK 8 و 9، أما للإصدارات الأحدث فيجب تنزيله بشكل منفصل من الموقع الرسمي.
\n\nلنكتب كودًا بسيطًا "بطيئًا" للاختبار. أنشئ فئة SlowApp.java:
import java.util.ArrayList;\nimport java.util.List;\nimport java.util.Random;\n\npublic class SlowApp {\n public static void main(String[] args) throws InterruptedException {\n List<String> data = new ArrayList<>();\n Random random = new Random();\n\n // محاكاة تحميل بيانات طويل\n for (int i = 0; i < 100_000; i++) {\n data.add(generateString(random));\n }\n\n // معالجة البيانات\n long sum = 0;\n for (String s : data) {\n sum += processString(s);\n }\n\n System.out.println("Result: " + sum);\n Thread.sleep(10000); // لإتاحة الوقت للاتصال بالمحلل\n }\n\n private static String generateString(Random random) {\n StringBuilder sb = new StringBuilder(100);\n for (int i = 0; i < 100; i++) {\n sb.append((char) ('a' + random.nextInt(26)));\n }\n return sb.toString();\n }\n\n private static long processString(String s) {\n long result = 0;\n for (char c : s.toCharArray()) {\n result += c;\n // تأخير اصطناعي\n for (int j = 0; j < 100; j++) {\n result += Math.sqrt(j);\n }\n }\n return result;\n }\n}\n\nقم بتشغيل التطبيق:
\njavac SlowApp.java\njava SlowApp\n\nأثناء تشغيل البرنامج (سينام لمدة 10 ثوانٍ)، افتح VisualVM. في اللوحة اليسرى، ابحث عن عمليتك (SlowApp) وانقر نقرًا مزدوجًا. انتقل إلى علامة التبويب Sampler أو Profiler - سترى إحصائيات المعالج والذاكرة.
\n\n2. تحليل المعالج: إيجاد الدالة الأكثر استهلاكًا
\n\nفي VisualVM، اضغط على زر CPU في قسم Sampler. بعد بضع ثوانٍ، ستحصل على جدول بالدوال مرتبة حسب وقت التنفيذ (Self Time).
\n\nفي مثالنا، سترى أن الدالة processString تستهلك أكثر من 80% من الوقت. داخلها، الحلقة المتداخلة Math.sqrt(j). هذه هي نقطة الاختناق.
كيف نفسر ذلك؟
\n- \n
- Self Time - الوقت المستغرق مباشرة في تنفيذ الدالة (بدون احتساب استدعاءات الدوال الفرعية). \n
- Total Time - الوقت الإجمالي بما في ذلك جميع الاستدعاءات المتداخلة. \n
- Invocations - عدد مرات استدعاء الدالة. \n
مثال على المخرجات (مبسط):
\nMethod Self Time (ms) Invocations\nSlowApp.processString 8500 100000\nSlowApp.generateString 1200 100000\njava.lang.Math.sqrt 6000