Borna66
01-02-2010, 04:17 PM
مدیریت حافظه در دلفی
تخصیص خودکار حافظه
وقتی شما از نوعهای پایه (Integer ،real ،word و…) برای ایجاد متغییرهای خود استفاده می کنید، هیچ نگرانی درباره تخصیص حافظه آن وجود ندارد چون دلفی خودش آنرا تخصیص حافظه می کند و سپس آزاد میکند.
type
TDay = (Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday)
var
Name : String; {256 Bytes}
X, Y : Integer; {4 + 4 = 8 Bytes}
List : array [0..10] of Double; {8 * 11 = 88 Bytes}
Today : TDay; {1 Byte}
دراین نمونه پس از پایان برنامه، تمام حافظه تخصیص داده شده فراخوانی و آزاد می شود.
تخصیص حافظه دینامیکی
در این حالت برنامه نویس احتیاج دارد تا انباره حافظه را شخصا" تخصیص و آزاد کند.
نوع Pointer
اشارهگرها در دلفی میتوانند شکلهای مختلفی را در برگیرد. نخست، نوع اشارهگری که یک آدرس حافظه را برای نوع ویژهای از داده، همانند صحیح، رشته و غیره نگه میدارد (Typed Pointer).
var
;Number : ^Integer
;Name : ^String
دوم، اشارهگرهای بدون نوع. اشارهگرهای بدون نوع (Untyped Pointers) خیلی به نوع معمولی خود شبیه هستند. اما محدودیتهایی مثل اینکه باید به نوع خاصی اشاره (Point) کند را ندارد.
var ;Something : Pointer
حال اشارهگر بدون نوع ما می تواند به هر نوعی از داده اشاره کند. برای تخصیص حافظه آن، از کمپلکس بیش از یک بیت استفاده میکنیم. برای مثال برنامه زیر کامپایل می شود ولی در زمان اجرا حافظهای تخصیص نمیشود.
begin
New(Something);
Dispose(Something);
end;
برای تخصیص حافظه کامپایلر باید بداند که نوع داده ما برای تخصیص حافظه چیست:
type
IntPtr = ^Integer;
var
Something : Pointer;
begin
Something := New(IntPtr);
Integer(Something^) := 10;
Dispose(Something);
end;
تخصیص بلاکی از حافظه
ما میتوانیم از اشاره به بلاکهایی از تخصیص حافظه در سیستم استفاده کنیم. این کار را با رویههای GetMem و FreeMem برای تخصیص و آزاد سازی حافظه استفاده میکنیم.
var
Something : Pointer
begin
GetMem(Something, 100);
FreeMem(Something, 100);
end;
اشاره به حافظه از قبل تخصیص داده شده
هر دو نوع اشارهگرها می توانند به هر جایی از حافظه اشاره بکنند. این بدان معناست که آنها میتوانند اشاره به فضای اشغال شده با دادههایی که در حال حاضر موجودند داشته باشند. این نمونه اشارهگر احتیاجی به تخصیص حافظه ندارد.
var
Something : Pointer;
MyString : PChar; // type PChar = ^Char;
begin
GetMem(Something, 100);
MyString := Something;
StrCopy(Something, 'Hello World');
FreeMem(Something, 100);
end;
حافظه Heap
Heap شامل قسمتی از حافظه موجود در یک برنامه است که آنرا حافظه پویا می نامیم. Heap بخشی است که در آن تخصیص و تعریف حافظه به صورت تصادفی (Random) اتفاق میافتد. این به آن معناست که اگر شما سه بلاک از حافظه را به طور متوالی تخصیص دهید، می توانید بعد از هر دستور آنرا از بین ببرید. مدیر Heap جزئیات را برای شما نگهداری می کند. بنابراین شما به سادگی می توانید یک حافظه جدید را با GetMem و یا بوسیله صدا زدن constructor هنگام ساختن یک شی درخواست کنید و دلفی به شما یک بلاک جدید را برخواهد گرداند. Heap یکی از سه فضای موجود در برنامه کاربردی را استفاده کرده و دوتای دیگر به صورت فضای یکپارچه (Global) و پشته قرار می گیرند.
حافظه Stack
Stack شامل قسمتی از یک بخش از حافظه موجود یک برنامه است که دینامیکی است اما برای تخصیص و آزادسازی فرامین مخصوص دارد. تخصیص Stack به صورت LIFO می باشد. این بدان معناست که آخرین حافظه شیء شما تخصیص داه خواهد شد و سپس حذف می شود. حافظه پشته در روتینهای نوعی استفاده میشود. وقتی شما یک روتین را صدا میزنید، پارامترهایش و روتین نوع آن در پشته ریخته می شود. همچنین پارامترهایی که در یک روتین تعریف میشوند، در پشته ذخیره میشوند و وقتی روتین خاتمه پیدا می کند تمام آنها به طور خودکار از بین می رود.
تخصیص خودکار حافظه
وقتی شما از نوعهای پایه (Integer ،real ،word و…) برای ایجاد متغییرهای خود استفاده می کنید، هیچ نگرانی درباره تخصیص حافظه آن وجود ندارد چون دلفی خودش آنرا تخصیص حافظه می کند و سپس آزاد میکند.
type
TDay = (Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday)
var
Name : String; {256 Bytes}
X, Y : Integer; {4 + 4 = 8 Bytes}
List : array [0..10] of Double; {8 * 11 = 88 Bytes}
Today : TDay; {1 Byte}
دراین نمونه پس از پایان برنامه، تمام حافظه تخصیص داده شده فراخوانی و آزاد می شود.
تخصیص حافظه دینامیکی
در این حالت برنامه نویس احتیاج دارد تا انباره حافظه را شخصا" تخصیص و آزاد کند.
نوع Pointer
اشارهگرها در دلفی میتوانند شکلهای مختلفی را در برگیرد. نخست، نوع اشارهگری که یک آدرس حافظه را برای نوع ویژهای از داده، همانند صحیح، رشته و غیره نگه میدارد (Typed Pointer).
var
;Number : ^Integer
;Name : ^String
دوم، اشارهگرهای بدون نوع. اشارهگرهای بدون نوع (Untyped Pointers) خیلی به نوع معمولی خود شبیه هستند. اما محدودیتهایی مثل اینکه باید به نوع خاصی اشاره (Point) کند را ندارد.
var ;Something : Pointer
حال اشارهگر بدون نوع ما می تواند به هر نوعی از داده اشاره کند. برای تخصیص حافظه آن، از کمپلکس بیش از یک بیت استفاده میکنیم. برای مثال برنامه زیر کامپایل می شود ولی در زمان اجرا حافظهای تخصیص نمیشود.
begin
New(Something);
Dispose(Something);
end;
برای تخصیص حافظه کامپایلر باید بداند که نوع داده ما برای تخصیص حافظه چیست:
type
IntPtr = ^Integer;
var
Something : Pointer;
begin
Something := New(IntPtr);
Integer(Something^) := 10;
Dispose(Something);
end;
تخصیص بلاکی از حافظه
ما میتوانیم از اشاره به بلاکهایی از تخصیص حافظه در سیستم استفاده کنیم. این کار را با رویههای GetMem و FreeMem برای تخصیص و آزاد سازی حافظه استفاده میکنیم.
var
Something : Pointer
begin
GetMem(Something, 100);
FreeMem(Something, 100);
end;
اشاره به حافظه از قبل تخصیص داده شده
هر دو نوع اشارهگرها می توانند به هر جایی از حافظه اشاره بکنند. این بدان معناست که آنها میتوانند اشاره به فضای اشغال شده با دادههایی که در حال حاضر موجودند داشته باشند. این نمونه اشارهگر احتیاجی به تخصیص حافظه ندارد.
var
Something : Pointer;
MyString : PChar; // type PChar = ^Char;
begin
GetMem(Something, 100);
MyString := Something;
StrCopy(Something, 'Hello World');
FreeMem(Something, 100);
end;
حافظه Heap
Heap شامل قسمتی از حافظه موجود در یک برنامه است که آنرا حافظه پویا می نامیم. Heap بخشی است که در آن تخصیص و تعریف حافظه به صورت تصادفی (Random) اتفاق میافتد. این به آن معناست که اگر شما سه بلاک از حافظه را به طور متوالی تخصیص دهید، می توانید بعد از هر دستور آنرا از بین ببرید. مدیر Heap جزئیات را برای شما نگهداری می کند. بنابراین شما به سادگی می توانید یک حافظه جدید را با GetMem و یا بوسیله صدا زدن constructor هنگام ساختن یک شی درخواست کنید و دلفی به شما یک بلاک جدید را برخواهد گرداند. Heap یکی از سه فضای موجود در برنامه کاربردی را استفاده کرده و دوتای دیگر به صورت فضای یکپارچه (Global) و پشته قرار می گیرند.
حافظه Stack
Stack شامل قسمتی از یک بخش از حافظه موجود یک برنامه است که دینامیکی است اما برای تخصیص و آزادسازی فرامین مخصوص دارد. تخصیص Stack به صورت LIFO می باشد. این بدان معناست که آخرین حافظه شیء شما تخصیص داه خواهد شد و سپس حذف می شود. حافظه پشته در روتینهای نوعی استفاده میشود. وقتی شما یک روتین را صدا میزنید، پارامترهایش و روتین نوع آن در پشته ریخته می شود. همچنین پارامترهایی که در یک روتین تعریف میشوند، در پشته ذخیره میشوند و وقتی روتین خاتمه پیدا می کند تمام آنها به طور خودکار از بین می رود.