باز کردن منو اصلی

تغییرات

←‏المان‌ها: + مدیریت منابع و نشت حافظه، ابرابزار
 
=== معناشناسی ایستا ===
معناشناسی ایستا محدودیت‌هایی بر روی ساختار مجاز متن‌ها تعیین می‌کند که بیان آنها در فرمول دستوری استاندارد مشکل یا غیرممکن است. مهمترین این محدودیت‌ها به وسیله [[سیستم نوع]] گذاری انجام می‌شود. برخلاف باور برخی از برنامه‌نویسان محدودیت‌های اعمال شده، اعمال نشده‌اند بلکه در واقع ناشی از زیرساخت‌های آن زبان برنامه‌نویسی هستند تا سرعت پردازش را افزایش دهند و قدرت پردازش پردازنده را برای تایپ‌کستینگ‌های خودکار متعدد صرف نکنند. استفاده از روش ایستا صرفاصرفاً سرعت پردازش‌هایی را افزایش می‌دهد که در کسری از ثانیه به محاسبه حجم انبوهی از داده‌ها نیاز دارند. این موضوع بهبود پردازش برای مثال خودش را در گرافیک‌های سنگین بازی‌های کامپیوتری نشان می‌دهد همچنین برای مثال در سرورهای بک‌اند (پشتی) بانکداری با حکمحجم انبوهی از ثبت ترنزاکشن‌ها که از زبان ایستای جاوا استفاده می‌شود اما حتی در موضوع گرافیک جاوا به دلیل استفاده از گاربیج‌کالکشن یا جمع‌آوری زباله و البته استفاده از ماشین مجازی برای مدیریت حافظه سرعت پردازشی C++ را ندارد از طرفی استفاده دات نت از زبان میانجی IL برای پشتیبانی از زبان‌های متعدد مانند C# یا F# و کامپایل نکردن مستقیم به باینری ماشینی باعث می‌شود که سرعت پردازش C# نیز از جاوا پایین‌تر باشد اما امکانات گسترده‌تری را در زمینه‌های خاصی مانند طراحی وب یا ساخت برنامه‌های سبک‌پردازشی روی سیستم‌عامل را فراهم کند اگرچه با صرف میزان بیشتری از منابع حافظه و پردازشی.
 
=== سیستم نوع گذاری ===
 
نوع گذاری قوی مانع رخ دادن مشکل فوق می‌شود. تلاش برای انجام عملیات روی نوع نادرست متغیر منجر به رخ دادن خطا می‌شود. زبان‌هایی که نوع گذاری قوی دارند غالباً با نام «نوع-امن» یا امن شناخته می‌شوند.
تمام تعاریف جایگزین برای «ضعیف نوع گذاری شده» به زبان‌ها اشاره می‌کند، مثل perl, JavaScript, C++، که اجازه تعداد زیادی تبدیل نوع داخلی را می‌دهند. در جاوااسکریپت، برای مثال، عبارت ۲*x به صورت ضمنی x را به عدد تبدیل می‌کند، و این تبدیل موفقیت آمیزموفقیت‌آمیز خواهد بود حتی اگر x خالی، تعریف نشده، یک آرایه، یا رشته‌ای از حروف باشد. چنین تبدیلات ضمنی غالباً مفیدند، اما خطاهای برنامه‌نویسی را پنهان می‌کنند.
 
قوی و ایستا در حال حاضر عموماً دو مفهوم متعامد فرض می‌شوند، اما استفاده در ادبیات تفاوت دارد، برخی عبارت «قوی نوع گذاری شده» را به کار می‌برند و منظورشان قوی، ایستایی نوع گذاری شده‌است، و یا، حتی گیچ کننده تر، منظورشان همان ایستایی نوع گذاری شده‌است؛ بنابراین C هم قوی نوع گذاری شده و هم ضعیف و ایستایی نوع گذاری شده نامیده می‌شود.
 
=== کتابخانه هسته ===
اغلب زبان‌های برنامه‌نویسی یک کتابخانه هسته مرتبط دارند (گاهی اوقات "کتابخانه استاندارد" نامیده می‌شوند، مخصوصاً وقتی که به عنوان قسمتی از یک زبان استاندارد ارائه شده باشد)، که به طوربه‌طور قراردادی توسط تمام پیاده‌سازی‌های زبان در دسترس قرار گرفته باشند. کتابخانه هسته معمولاً تعریف الگوریتم‌ها، داده ساختارها و مکانیزم‌های ورودی و خروجی پرکاربرد را در خود دارد.
کاربران یک زبان، غالباً با کتابخانه هسته به عنوان قسمتی از آن رفتار می‌کنند، اگرچه طراحان ممکن است با آن به صورت یک مفهوم مجزا رفتار کرده باشند. بسیاری از خصوصیات زبان هسته‌ای را مشخص می‌کنند که باید در تمام پیاده‌سازی‌ها موجود باشند، و در زبان‌های استاندارد شده این کتابخانه هسته ممکن است نیاز باشد؛ بنابراین خط بین زبان و کتابخانه هسته آن از زبانی به زبان دیگر متفاوت است. درواقع، برخی زبان‌ها به گونه‌ای تعریف شده‌اند که برخی از ساختارهای دستوری بدون اشاره به کتابخانه هسته قابل استفاده نیستند.
برای مثال در جاوا، یک رشته به عنوان نمونه‌ای از کلاس “java.lang.String” تعریف شده‌است؛ مشابها، در سمال تاک(smalltalk) یک تابع بی‌نام (یک "بلاک") نمونه‌ای از کلاس BlockContext کتابخانه می‌سازد. بطور معکوس، Scheme دارای چندین زیرمجموعه مرتبط برای ایجاد سایر ماکروهای زبان می‌باشد، و در نتیجه طراحان [[زبان حتی]] این زحمت را نیز تحمل نمی‌کنند که بگویند کدام قسمت زبان به عنوان ساختارهای زبان باید پیاده‌سازی شوند، و کدام یک به عنوان بخشی ازکتابخانه.
 
=== مدیریت منابع و نشت حافظه ===
مدیریت منابع به دوشاخه پردازش و حافظه (موقت یا دائم یا دورگه (موقت مجازی)) تقسیم می‌شود و در یک عبارت خلاصه می‌شود:در ایده‌آل‌ترین حالت صرفه‌جویی در حافظه، میزان پردازش را افزایش می‌دهد و صرفه‌جویی در پردازش، حافظه مصرفی را افزایش می‌دهد (این موضوع در بانک‌های اطلاعاتی با عنوان نرمالیزیشن و دینرمالیزیشن شناخته می‌شود). مقدار حافظه اختصاص داده شده برای یک متغیر عدد کوتاه ۸ بیتی در زبان ایستا قابل مقایسه با یک متغیر طولانی ۳۲بیتی نیست که این موضوع در زبان ایستا به صراحت و مستقیم توسط کد نوشته‌شده برنامه‌نویس تعیین می‌شود (در زبان پویا نیاز به اجرای کد زیرساختاری اضافی کوچک دیگری هست تا تشخیص دهد که چه نوع مقداری به این متغیر اختصاص داده شده؟ استرینگ رشته یا عدد بزرگ یا کوچک؟). این تفاوت ظرفیت عددها در زمان تفکیک برنامه‌های ۶۴بیتی در مقایسه با برنامه‌های ۳۲بیتی حتی برای عموم مردم کاملاً فاحش می‌شود (با اشاره به این نکته حاشیه‌ای که برنامه‌های ۳۲بیتی به دلیل محدودیت عددی توان اندازه‌گیری حافظه بیشتر از ۴میلیارد و اندی بایت را ندارند که معادل ۴گیگابایت است که درمبنای ۲ به توان ۳۲ محاسبه شده باشد در نتیجه سیستم‌عامل ۳۲بیتی نمی‌تواند روی یک سیستم با رَم بیش از ۴ گیگابایت نصب شود).
 
تفاوت زبان‌های پویا با ایستا فقط در تعریف نوع متغیر نیست بلکه همان‌طور که دربارهٔ اعداد مطرح شد به زمینه مدیریت حافظه یا مموری منیجمنت نیز کشیده می‌شود همچنین بارگذاری خودکار کتابخانه‌ها و گسترده کردن کتابخانه‌های محیط اجرای برنامه. البته زبان‌های ایستای مدرن مانند C# با زبان میانجی IL یا جاوا و ماشین مجازی‌اش از مدیریت حافظه بهره می‌برند و به نوعی دورگه و هایبرد هستند تا تعادلی بین مدیریت حافظه و مدیریت پردازش را بدون تایپ‌کستیگ ایجاد کنند.
 
تفاوت سرعت پردازش زبان‌های ایستا و پویا در برنامه‌هایی که نیاز به پردازش‌های بسیار حجیم در مدت زمان بسیار کوتاه دارند خودش را نشان می‌دهد بنابراین تفاوت سرعت پردازش در مورد حتی وبگاه‌های بسیار شلوغ آنقدر نیست که امکانات فراهم شده توسط یک زبان سطح بالا مانند php یا python را فدای سرعت php کنند البته برای مثال فیسبوک مجبور شد که php را بواسطه c++ بر روی facebook hiphop گسترش دهد تا به سرعت پردازش مطلوب خودش برسد. برای مثال درباره python توصیه شده‌است که حلقه‌های چرخشی روی حجم بالای داده را بواسطه لوپ خود پایثون و با اندیس index انجام ندهید بلکه یک آرایه array تهیه کرده و چرخش را به زیرساخت C++ آن واگذار کنید.
 
اما مساله مدیریت حافظه و نشت آن یا memory leakage از آنجاست که در زمان اجرای برنامه (runtime) ابتدا فضایی از حافظه به نام کداسپیس به کد اختصاس داده می‌شود و به بقیه حافظه در دسترس heap گفته می‌شود. مسئولیت استفاده و تضمین خالی کردن بخش اشغال‌شده از heap پس از پایان کار به عهده خود برنامه‌نویس است در غیر اینصورت برنامه ممکن است دچار نشت حافظه شود. در زمان ران‌تایم جدولی از کداسپیس درون ساختار زبان برای تعیین حافظه مورد استفاده هر بخش از کد (مثلا یک تابع یا فانکشن) اختصاص داده می‌شود که به هر بخش از آن اصطلاحاً Scope گفته می‌شود که تعیین می‌کند که کدام متغیرها توسط کدام بخش از کد استفاده می‌شوند تا در آغاز یک scope آن متغیرها درون محیط مثلا یک تابع ایجاد شوند و پس از اجرا کاملا پاک شوند (کسانی که در محیط ساده [[بورن شل]] کار کرده‌اند با این موضوع به خوبی آشنا می‌شوند). اما در زمان استفاده از ریفرنس خارجی در قالب pointer (اختصاصی زبان C++) آن متغیری که به ظاهر در محیط اسکوپ استفاده می‌شود در واقع فقط یک میان‌بر ریفرنس است به پوینتری که فضایی را روی حافظه تعیین کرده است که خارج از محدوده اسکوپ مثلا تابع فعلی ما قرار دارد در نتیجه با پایان کار فانکشن ما، فضای اختصاصی آن پوینتر تخلیه نمی‌شود بلکه فقط متغیر ریفرنسی که به آن اشاره می‌کرده پاک می‌شود و نشت حافظه رخ می‌دهد (به آن pointer که هیچ متغیر ریفرنسی نداشته باشد پوینتر وحشی یا wild گفته می‌شود) و این پوینتر می‌تواند یک شی بانک اطلاعاتی دارای حجم انبوهی از داده‌های استخراج شده باشد یا یک شی ارتباطی بانک اطلاعاتی که از دسترس خارج شده‌اند اما فضای حافظه را تا زمان باز بودن برنامه اشغال می‌کنند. ریفرنس‌های پوینتر حتی در زبان‌های سطح بالا مانند php و python یا C# هنوز در لایه زیرین ناپیدا استفاده می‌شوند برای انتقال متغیرها در سراسر برنامه اما زبان سطح بالا تعداد ریفرنس‌های موجود به هر پوینتر را حفظ می‌کند و زمانی که این تعداد صفر بشود زمان مرگ پوینتر و تخلیه آن فرا رسیده یا آن را به سطل زباله گاربیج‌کالکشن می‌فرستد تا همه آنها را با هم و در یک نوبت تخلیه کند و از بار پردازشی اضافه ناشی از تخلیه مکرر بکاهد اگرچه تعداد نوبت‌های تخلیه گاربیج‌کالکشن در تنظیمات برنامه یا سرور ماشین مجازی قابل تنظیم است.
 
== عمل ==