نگاهی عمیق به مباحث جاوا با Java Zone


قسمت اول Java Zone

سلام. قبل از شروع، فنجون قهوه اتون رو کنارتون بذارید تا بگم قراره توی این سری ها در مورد چی گپ بزنیم.

سری Java Zone قراره تا حدی ما رو از دانش ابتدایی و عمومی نسبت به جاوا فراتر ببره و تو این مسیر با کلی نکته های ریز و نسبتا عمیق آشنا بکنه. سعی میکنم با اشاره به بخش های مختلف این سری هارو به جاهای باریک بکشونم و در آخر راضی باشیم دورهم:))))

پس بهتره برای ارتباط برقرار کردن بیشتر با این سری، نسبتا با جاوا آشنا باشی. خب بریم.



طوری که جاوا کار میکنه


  • سورس کد: کدی که مینویسی
  • کامپایلر: وظیفه اش اینه که چک میکنه خطایی رخ نداده باشه. (املایی و منطقی)
  • اگه همه چی روبه راه بود، کامپایلر سورس رو به جاوا-بایت کد تبدیل میکنه.
  • ماشین مجازی جاوا (JVM): در آخر بایت کد هارو میخونه و اجراشون میکنه.


بایت کد دقیقا چیه؟

بایت کد که به عنوان " Portable code" یا "P-code" هم شناخته میشه، یک کد میانی شبیه به کد ماشینه. برعکس کد منبع که برای انسان قابل خوندنه، بایت کد ها کدهای عددی فشرده، ثابت‌ها و ارجاعی (معمولا آدرس‌های عددی) هستن. استفاده ازشون به JVM اجازه میده عملکرد بهتری توی خوندن و اجرا داشته باشه.

اگه بخواین خود بایت کد رو تصور کنین چه شکلیه، این تیکه رو ببیین.

بعضی از دستوراتش اینجوریه

iaload: بازیابی int از آرایه
istore: ذخیره
i2b: تبدیل int به بایت
aload_0: بازیابی

میتونید از اینجا و اینجا بیشتر باهاش آشنا بشین.

کامپایلر جاوا

وظیفه تبدیل سورس کد به بایت کد رو داره. javac یکی از کامپایلرهای جاواست که این عمل رو انجام میده. البته به جز این، Jikes هم بود که با C++ نوشته شده و فکر کنم دیگه توسعه اش متوقف شده. یکی از رایج ترین حالت های خروجی کامپایلر جاوا، کلاس-فایل ها هستن که توسط JVM اجرا میشن. JVM کلاس-فایل ها رو لود میکنه سپس بایت کدهارو به کد ماشین تبدیل میکنه. البته اینم اضافه کنم که بعضی از زبان ها بجای کامپایل، توسط مفسرها تفسیر میشن.

فرق کامپایلر با مفسر چیه؟

هم کامپایلر و هم مفسر به کار ترجمه کد منبع مشغوله تا در نهایت به کد ماشین تبدیل بشه و این کار رو یا از طریق ترجمه در یک مرحله (کامپایلر) یا با تفسیر و اجرای خط به خط کد (مفسر) انجام میده.

مخلوطی از کامپایلر و مفسر (JIT)

در ابتدا JIT مثل یک مفسر عمل میکنه و کد رو در زمان فراخوانی اجرا میکنه. اگرم کدی پیدا کنه که بارها و بارها فراخوانی شده، مانند کامپایلر عمل می‌کنه. JIT همیشه کد تحت اجرا رو در نظر داره. کدهایی که مشکوک به تکرار هستن رو علامت گذاری میکنه و اونهارو بجای تفسیر، کامپایل میکنه. JIT اساساً مثل مفسر عمل می‌کنه؛ مگر این که متوجه بشه در موردی یک دسته از کارها دارن تکراری انجام میشن. در این حالت JIT رفتارش میشه مثل کامپایلر و کدهای با فراخوانی مکرر رو از طریق کامپایل مستقیم، بهینه‌سازی میکنه.

در ادامه می‌پردازیم به اینکه عدم بهینه‌سازی هوشمند از سوی JIT چطوری میتونه منجر به بهینه‌سازی ضعیف بشه.

فرض کن یک مورد تکراری برای JIT پیش اومده. مشخصه که JIT اون رو به عنوان کد تکراری علامت‌گذاری کرده و تصمیم گرفته کامپایل اش کنه. اما اهمیت روشی که JIT برای کامپایل کردن انتخاب می‌کنه به اندازه کامپایل کردن اون مهمه.JIT میتونه انواع متفاوتی از کامپایل رو اجرا کنه که برخی از اون‌ها سریع و برخی دیگر پیچیده‎ ترهستن.

مگه چند نوع کامپایل داریم؟؟
مگه چند نوع کامپایل داریم؟؟


بریم ببینیم چند نوع داریم.

  • کامپایل مبنا: یک کامپایل سریع اصولا بهینه‌سازی عملکردی پایین‌تری داره و شامل کامپایل کردن کد و سپس ذخیره ‌سازی نتیجه کامپایل بدون صرف زمان زیاد هست. این شکل از بهینه‌سازی سریع به نام بهینه‌ سازی مبنا Baseline Optimization معروفه.
  • کامپایل بهینه: JIT میتونه نوع عمیق‌تر و طولانی‌تری از بهینه‌سازی عملکرد که به نام کامپایل بهینه هست رو استفاده کنه. این نوع کامپایل شامل صرف زمان زیاد در ابتدا و سرمایه‌گذاری برای بهینه‌سازی یک بخش از کد هست که کارآمدترین حالت ممکن رو برای کد به وجود میاره.



کامپایل مبنا رو میشه به نوعی متضاد کامپایل بهینه دونست

نتیجتا کامپایل مبنا تا حدودی شبیه به ویرایش یک مقاله از نظر املا و دستور زبانه. در این حالت ما بهبودهای عمیقی روی مقاله ایجاد نمی‌کنیم؛ بلکه چند بهبود جزئی اجرا می‌کنیم. کامپایل بهینه به نوعی مثل ویرایش محتوایی، مفهومی و خوانایی یک مقاله است. طبیعتا در کامپایل بهینه هم کار بیشتری انجام و هم زمان بیشتری سپری میشه؛ اما در نهایت نتیجه بهتری داره.




خب فکنم تا همینجا برای این سری کافی باشه تو سری بعدی قراره بریم سراغ JVM.

طبق معمول هر پایانی اگه سوالی، پیشنهادی یا مورد خاصی بود حتما کامنت کنید.

تا سری بعد ??