افزونه .NET Portability Analyzer
نصب Mono Develop 4.x در Ubuntu
اگر یک برنامه جدید را در monodevelop شروع کردید و به خطای کامپایل ذیل برخوردید:
Error: A dependency of a referenced assembly may be missing, or you may be referencing an assembly created with a newer CLR version. See the compilation output for more details. (Test1)
export PATH=/opt/mono-3/bin:$PATH export PKG_CONFIG_PATH=/opt/mono-3/lib/pkgconfig:$PKG_CONFIG_PATH mono -V
Garbage Collection
فرض کنید متغیری را ایجاد کرده و به آن مقدار دادهاید:
string message = "Hello World!";
آیا تابحال به این موضوع فکر کردهاید که طول عمر متغیر message تا چه زمانی است و چه زمانی باید از بین برود؟
چه زمانی باید توسط کامپایلر ( یا بهتر بگوییم ، Runtime ) طول عمر این متغیر به پایان برسد و از حافظه حذف شود؟
- Unmanaged: در این دسته از زبان ها، وظیفهی ایجاد اشیاء، تشخیص زمان درست برای از بین بردن و از بین بردن آنها، برعهدهی شماست. زبانهای C و ++C جز این نوع زبانها میباشند.
- Managed: در این دسته از زبانها، ایجاد اشیاء مانند قبل بر عهدهی شماست، اما وظیفه تشخیص و از بین بردن آنها در زمان درست را Runtime برعهده میگیرد.
در این نوع زبانها ما دغدغهی حذف متغیری را که در چندین خط بالاتر، آن را ایجاد کرده و به آن مقدار داده، به چندین متد آن را پاس داده و انواع تغییرات را روی آن انجام دادهایم، نداریم. زبانهای #C و Java جزو این نوع زبانها میباشند.
ایده کلی ایجاد زبانهای Managed بر این است که شما درگیر مباحث مربوط به Memory Management نشوید و تمرکز اصلیتان روی Business باشد.
اکثر پروژهها به اندازه کافی پیچیدگیهای Business ای دارند و ترکیب کردن این نوع پیچیدگیها با پیچیدگیهای Low Level و Technical ای همچون مباحث Memory Management، در اکثر اوقات باعث میشود که نگهداری از پروژه کاری بسیار دشوار شده و به تدریج مانند بسیاری از پروژههای دیگر، نام Legacy را با خود به یدک بکشد.
این بدان معنا نیست که پروژههایی که با زبان هایی همچون C و ++C نوشته میشوند، از همان روز اول Legacy بوده و قابل نگهداری نیستند، بلکه بدین معناست که نگهداری کد چنین زبانهایی نسبت به زبانهای Managed، به مراتب مشکلتر است و همچنین قابل ذکر است که قابلیت نگهداری یک پروژه به مباحث بسیار زیاد دیگری نیز بستگی دارد.
کد این برنامه در زبان C :
#include <stdio.h> #include <stdlib.h> void printReport(int* data) { printf("Report: %d", *data); } int main(void) { int *myNumber; myNumber = (int*)malloc(sizeof(int)); if (myNumber == 0) { printf("ERROR: Out of memory"); return 1; } *myNumber = 25; printReport(myNumber); free(myNumber); myNumber = NULL; return 0; }
"هدف" و Business اصلی این برنامه، چاپ و یک گزارش ساده بود، اما مسائل بسیار بیشتری در این مثال دخیل شده اند:
چند مرحله از این مراحل ذکر شده، واقعا نیاز Business ای برنامه ما بود؟ این مثال، بسیار ساده و غیر واقعی بود؛ اما تصور کنید با این روش، یک برنامه بزرگ با Business Ruleها و پیچیدگیهای خودش، چه حجمی از کد و پیچیدگی را خواهد داشت.
کد این برنامه در زبان #C :
using System; public class Program { public static void Main() { int myNumber = 25; PrintReport(myNumber); } private static void PrintReport(int number) { Console.WriteLine($"Report: {number}"); } }
همانطور که میبینید در اینجا تمرکزمان روی هدف اصلی و Business است و درگیر پیچیدگی مباحث جانبی نظیر Manual Memory Management نشدهایم و Runtime زبان #C یعنی CoreCLR وظیفه Memory Management را در پشت صحنه برعهده گرفته است.
تفاوت بین زبانهای Managed و Unmanaged را میتوانیم به رانندگی با ماشین دندهای و اتومات تشبیه کنیم.
اکثر اوقات هدف اصلی رانندگی، رفتن از یک مبدا به یک مقصد است. با استفاده از یک ماشین دندهای، علاوه بر هدف اصلی یعنی رسیدن به یک مقصد، ذهن ما درگیر تعویض دنده در سرعت مناسب در طول مسیر میشود و اینکار را ممکن است بیش از صدها یا هزاران بار انجام دهیم. در این روش طبیعتا ما کنترل بیشتری داریم و در بعضی مواقع بسیار بهتر به نسبت یک سیستم خودکار عمل میکنیم، اما از هدف اصلی خود یعنی رفتن از نقطه A به B دور شدهایم.
در زبانهای Managed و Unmanaged هم دقیقا چنین تفاوت هایی وجود دارد.
در زبانهای Unmanaged، شما کنترل کاملی را روی طول عمر اشیا و مدیریت حافظه دارید و همه چیز برعهده شماست؛ اما علاوه بر هدف اصلیتان، درگیر مباحث جانبی دیگری نیز شدهاید. اکثر اوقات قدرت زبانهای Unmanaged را در Game Engineها و Real-Time Processing Systemها میتوانید ببینید که در آنها مدیریت حافظه بصورت دستی انجام میشود و برنامه نویسهای آن سیستم، تعیین کننده اصلی این هستند که طول عمر اشیاء تا چه زمانی باشد و چه زمانی از بین بروند که باعث اختلال یا کندی یک سیستم حتی برای چند میلی ثانیه نشوند.
در زبانهای Managed، اکثر اوقات حتی نیازی نیست که شما درگیر مباحث جانبی مدیریت حافظه شوید و تمام کار را Runtime شما بصورت خودکار انجام میدهد. اما گاهی اوقات لازم است که قسمتهای حساس برنامه ( اصطلاحا Hot-Pathها ) خود را پیدا کنید، از این قسمتها Benchmark گرفته و مطمئن شوید که با حجم تعداد بالای درخواست و بار، به خوبی عمل میکند و همچنین قسمتی از برنامه، نشستی حافظه ( اصطلاحا Memory Leak ) ندارد. همانطور که گفتیم، گاهی اوقات یک انسان ( سیستم دستی ) بهتر از یک سیستم خودکار میتواند تصمیم بگیرد که در یک لحظه چه اتفاقی داخل برنامه رخ دهد.
در این سری مقالات قصد داریم وارد مبحث Memory Management در #C شده، با Garbage Collector آشنا و دیدی کلی از نحوهی انجام کار آن داشته باشیم.
خبرنامه هفتگی ASP.NET Core News
ASP.NET Core News is the only weekly newsletter dedicated to ASP.NET Core. Whether you build Razor Pages, MVC applications, Web APIs, SignalR awesomeness, or anything else available on the ASP.NET Core platform, we've got you covered. Every Friday you will receive a weekly digest of the most interesting posts and articles from the last seven days.
کتاب رایگان JWT Handbook
This command allows cleaning up project and assembly references that have no actual usages in source code. You can apply this command on a project, solution folder, or the entire solution. Before deletion is complete, you will be able to see all references that are going to be removed and. if necessary, preserve the ones that you want to keep.