Object Oriented Programming Pada Delphi - Bag 3

Pada artikel sebelumnya , kita telah mempelajari cara menggunakan kelas dan objek. Pada artikel berikut ini, saya akan membahas tentang bagaimana cara mengalokasikan dan membebaskan memori yang dipakai objek. Selamat mengikuti.


Pastikan bebaskan memori yang sudah tidak terpakai !

Perhatikan potongan program di bawah ini :
Procedure Test;
Var
i, j : Integer;
stringList1 : TStringList;

Begin
stringList1 := TStringList.Create;
i := 10;
j := 0;
i := i div j; // baris 10 – menimbulkan Exception
stringList1.Free; // baris 11 – tdk akan pernah dieksekusi
End;


Pada baris ke 10, program akan menampilkan eksepsi devide by zero. Jika kita jalankan kode di atas menggunakan debugger, kita akan lihat bahwa baris ke 11 tidak akan pernah dieksekusi. Memori yang di alokasikan untuk stringList1 tidak pernah dibebaskan. Contoh di atas mungkin akan jarang terjadi, namun yang jelas kita harus hati-hati ketika mengalokasikan memori , kita harus memastikan bahwa memori yang dialokasikan tadi bisa dibebaskan. Delphi menyarankan – dan saya juga – untuk selalu mengapit penulisan Create / Free dengan Try / Finally. Try / Finally merupakan bagian dari standar pemrograman Pascal, cara kerjanya saya jelaskan dibawah ini.

Dalam menggunakan Try/Finally kita akan menjumpai dua buah kelompok baris kode. Kelompok pertama terletak di antara Try dan Finally, sedangkan kelompok kedua terleta di antara finally dan end. Perhatikan potongan baris kode di bawah ini :
Try
kelompok 1
Finally
kelompok 2
End;

Jika ada baris kode di kelompok pertama menimbulkan eksepsi, maka delphi akan menjaankan baris kode yang berada di kelompok kedua sebelum menampilkan eksepsi. Jika kelompok pertama tidak menimbulkan ekspsi baris kode pada kelompok kedua tetap akan dijalankan. Oleh karena itu, baris kode pada kelompok kedua pasti akan diekseusi baik terjadi atau tidak eksepsi pada baris kode di kelompok pertama. Untuk memastikan program bisa membebaskan memori yang sudah tidak terpakai, panggillah procedure free pada kelompok kedua. Lihat pola standar berikut ini :
objek := namakelas.namaconstructor
Try
// Gunakan objek di sini
Finally
.Free;
End;


Perhatikan , kita harus memanggil constructor sebelum baris Try. Hal ini untuk mengantisipasi jika constructor gagal dieksekusi. Jika constructor gagal dieksekusi, delphi tidak akan mengalokasikan memori..Jika constructor dieksekusi setelah baris Try, delphi akan menjalankan baris kode pada kelompok kedua, hal ini akan memungkinkan delphi membebaskan memori yang belum dialokasikan. Dengan menempatkan constructor sebelum try, jika constructornya gagal dieksekusi maka delphi tidak akan mengeksekusi baris kode pada kelompok kedua.
Jika kita harus mengalokasikan dan membebaskan memori untuk lebih dari satu buah objek, penggunaan Try / Finally akan sedikit lebih komplek. Perhatikan potongan baris kode berikut ini :
Var
Student1 : TStudent;
StringListl : TStringList;

Begin
// alokasikan memori
StringListl := TStringList.Create;
Student1 := TStudent.Create;
Try
// akses data Student1 & StringList1
Finally
Student1.Free;
StringList.Free;
End;
Apakah baris kode di atas sudah memastikan procedure free akan dipanggil? Tidak. Jika constructor TStudent gagal dieksekusi, program tidak akan masuk padablok Try,oleh karena itu baris kode pada blok finally tidak akan dieksekusi,dan memori untuk StringList1 tidak akan dibebaskan. Solusi yang bisa kita lakukan adalah :
Var
Student1 : TStudent;
StringListl : TStringList;

Begin
// alokasikan memori
StringListl := TStringList.Create;
Try
Student1 := TStudent.Create;
Try
// akses data Student1 & StringList1
Finally
Student1.Free;
End;
Finally
StringList.Free;
End;

Baris kode di atas bisa dicompile, tapi penulisan baris kode seperti sangat membosankan; coba anda bayangkan jika kita harus create tiga objek atau lebih . Satu trik untuk menyederhanakan baris kode di atas bisa kita buat. Trik ini berdasarkan bahwa Free tidak akan dijalankan jika objeknya nil. Coba cek algoritma precedure Free di bawah ini :

// Delphi’s Free
If theObjectBeingReleased <> Nil Then
ReleaseTheMemory; // Self.Destroy


Sebelum membebaskan memori, procedure Free pertamakali akan mengecek apakah objeknya nil atau tidak. Berarti, apakah baris kode berikut ini aman ?

Var
Student1 : TStudent;
Begin
// Lupa inisialisasi
Student1.Free;


Jawabannya tergantung dari nilai Student1 ketika procedure Free dipanggil. Apakah Student1 nil? Tidak. Di Delphi, variable tidak diberi nilai awal. Perhatikan baris kode di bawah ini (saya jamin tidak akan menimbulkan error) :

Var
Student1 : TStudent;
Begin
Student1 := Nil;

// Lupa inisialisasi Student1
Student1.Free;


Bagaimana baris kode di atas bisa menyederhanakan penulisan baris kode yang mengharuskan kita mengalokasikan memori dan membebaskan memori dari banyak objek? Perhatikan, dengan memehami algoritma procedure Free berarti kita bisa menuliskan baris kode berikut ini :

Student1 := Nil;
Try
Student1 := TStudent.Create;
Finally
Student1.Free;
End;


Jika constructor gagal dijalankan bisa dipastikan procedure Free tidak akan gagal dieksekusi. Kenapa demikian? Ya, karena jika constructor gagal dieksekusi berarti objek tersebut tidak dialokasikan memori untuknya sehingga nilainya tetap nil. Jika objek bernilai nil, ketika dipanggil procedure Free tidak akan menimbulkan error..
Jadi , solusi yang bisa kita ambil ketika kita harus mengalokasikan memori untuk banyak objek bisa seperti baris berikut ini :

Var
Student1 : TStudent;
StringListl : TStringList;

Begin
Student1 := Nil;
StringList1 := Nil;
Try
StringListl := TStringList.Create;
Student1 := TStudent.Create;
// Akses data Student1 dan StringList1
Finally
Student1.Free;
StringList.Free;
End;


Penulisan baris kode yang awal , yaitu menuliskan try/finally di dalam try finally, merupakan solusi yang lebih aman, namun agak ribet. Sedangkan solusi yang kedua (dengan inisialisasi objek menjadi nil) enawarkan solusi penulisan baris kode yang singkat dan enak dibaca. Silahkan anda pilih sendiri.
Berbica mengenai kegagalan dalam membebaskan memori, sebenarnya ada beberapa tool yang bisa membantu kita dalam mendekteksi hal ini. Beberapa contoh antara lain : FastMM dan EukareLog. Silahkan pelajari kedua tool tersebut. Bersambung

0 comments:

Post a Comment