Langsung ke konten utama

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

Komentar

Postingan populer dari blog ini

Cara Efektif Menggunakan StringGrid

StringGrid merupakan salah satu VCL yang sangat berguna. Jika anda sudah familiar dengan Webbased Application, anda bisa analogikan StringGrid dengan Table. Table digunakan untuk meenampilkan data. Adapun StringGrid, selain sebagai komponen untuk menampilkan data, dia juga juga bisa sebagai tempat untuk memasukkan data, lihat gambar di bawah ini : Pada gambar di atas, saya menampilkan form jurnal umum sebagai contoh penggunaan StringGrid. Pada contoh di atas, stringgrid dipakai untuk memasukkan data item jurnal berupa Kode dan nama perkiraan, status Debet/Kredit dan Nominal. Untuk memanfaatkan Stringgrid saya mempunyai beberapa konstanta yang mencerminkan nomor urut kolom, misalnya _KolKode merujuk pada kolom Kode Perkiraan, _KolNama merujuk pada kolom Nama. Lebih jelasnya lihat baris kode berikut : Const _KolKode : Integer = 0; _KolNama : Integer = 1; _KolDK : Integer = 2; _KolNominal : Integer = 3; Konstanta-konstanta tersebut saya pakai di beberapa temp...

Tanda-tanda programmer buruk

Dalam dunia pekerjaan, ada berbagai cara untuk menjadi tidak efektif. Berikut adalah beberapa perilaku yang sering terjadi pada beberapa programmer yang pernah saya kerjakan selama bertahun-tahun: "Saya Seorang Insinyur Perangkat Lunak, Bukan Programmer"  Anda tahu seperti apa mereka. Mereka membawa keyboard mekanis ke kantor? Mereka tidak bisa ikut dalam pertemuan harian karena terlalu sibuk memikirkan masalah tersebut (hanya butuh 5 menit untuk menyampaikan apa yang Anda pikirkan). Berapa lama waktu yang dibutuhkan untuk mendapatkan latte? Saya tidak begitu yakin bagaimana seseorang bisa menjadi begitu sombong dengan pengalaman 3 tahun, tapi begitulah adanya. Saya suka mengesankan orang dengan gelar pekerjaan saya. Siapa? Apa maksud Anda, tidak ada yang peduli. Mungkin sebaiknya Anda menghabiskan lebih banyak waktu untuk bekerja dan sedikit waktu untuk memikirkan status Anda? Papan Tulis di Belakang  Beberapa orang di industri ini memiliki gelar. Saya pernah bekerja deng...

Singleton Pattern

Motivasi Kadang ada keadaan di mana kita hanya boleh memiliki satu instan dari suatu kelas. Sebagai contoh, kita hanya boleh memiliki satu window manager (atau satu sistem file atau satu spooler printer) pada satu aplikasi. Biasanya singleton digunakan untuk managemen sumber daya internal maupun eksternal secara terpusat dan bisa diakses dimanapun. Singleton merupkan salah satu design pattern yang paling sederhana. Singleton hanya melibatkan satu kelas yang bertanggung jawab untuk menginstansiasi dirinya sendiri dan pada saat yang bersamaan menyediakan akses secara global terhadap instan tersebut. Pada pattern singleton, instan bisa diakses dari manapun tanpa harus memanggil contructor dari kelas instan tersebut Tujuan • Memastikan bahwa satu kelas hanya bisa dibuat instannya sekali. • Menyediakan akses secara global terhadap instan singleton tersebut. Implementasi Pada bahasa pemrograman Java, implementasi dari singleton adalah dengan membuat sebuah atribut static pada...