Chào mừng đến với Diễn đàn lập trình - Cộng đồng lập trình.
Kết quả 1 đến 3 của 3
  1. #1
    Ngày tham gia
    Sep 2015
    Bài viết
    0

    Các loại reference trong Java: strong reference, soft reference, weak reference, phantom reference và ứng dụng

    Lời nói đầu

    Java có một hệ thống kiểu reference gồm nhiều dạng, mỗi loại có 1 tính chất đặc biệt riêng để ta có thể lựa chọn cho phù hợp với quá trình dọn dẹp của Garbage Collector.
    Java có 4 loại reference đó là:
    -Strong reference (tạm dịch: tham chiếu mạnh).
    -Soft reference (tạm dịch: tham chiếu mềm).
    -Weak reference (tạm dịch: tham chiếu yếu).
    -Phantom reference (tạm dịch: tham chiếu ma).

    Bốn loại reference theo thứ tự trên được xếp từ mạnh nhất đến yếu nhất.
    Reference càng mạnh thì garbage collector càng khó đủ điều kiện dọn dẹp đối tượng.
    Strong reference là loại reference mạnh nhất và thông dụng nhất, chúng chính là loại reference thông thường của Java.
    Ba loại reference còn lại được cung cấp trong package java.lang.ref và gọi chung là non-strong reference (tạm dịch: tham chiếu không mạnh). Các đối tượng của các class trong package này được gọi là reference object (tạm dịch: đối tượng tham chiếu).

    Phần 1: Các khái niệm và ví dụ


    1.Strong reference
    1.1.Khái niệm
    Trong khoa học máy tính, strong reference (tạm dịch: tham chiếu mạnh) là một loại reference thỏa mãn tính chất: Garbage collector sẽ không đủ điều kiện dọn dẹp các đối tượng có bất kỳ một chuỗi strong reference nào dẫn đến đối tượng đó.

    Chú thích:
    "Các đối tượng mà có bất kỳ một chuỗi strong reference nào dẫn đến đối tượng đó" nghĩa là ta có thể sử dụng các đối tượng đó mà KHÔNG cần phải dùng đến các loại tham chiếu không mạnh.Những đối tượng như vậy được gọi là strongly reachable object.
    Nói cách khác đơn giản hơn: <font color="DarkGreen">strong reference giữ cho đối tượng mà nó tham chiếu không bị garbage collector dọn đi mất
    .
    Trong Java các tham chiếu đối tượng thông thường đều là strong reference
    Ví dụ:

    Mã:
    List<String> names = new ArrayList<String>();
    Reference đến đối tượng được tạo là strong reference.

    1.2.Ví dụ
    Ví dụ 1:

    Mã:
    package refdemo; public class StrongRefDemo {    public static class Something {        protected void finalize() {            System.out.println("Đây là lời của tôi trước khi vĩnh biệt");        }    }      public static void main(String args[]) throws InterruptedException {        Something strong = new Something();        strong=null;        System.gc();        Thread.sleep(5000);  // Dòng này để trì hoãn không cho chương trình kết thúc ngay để ta có thể xem được kết quả thí nghiệm        System.out.println("Mọi thứ kết thúc");    }}
    Giải thích:
    Trong ví dụ trên, nếu có dòng strong=null thì đối tượng Something được tạo ra sẽ không còn có strong reference dẫn đến nó, do đó khi đề nghị Garbage Collector dọn dẹp bằng cách gọi lệnh System.gc() thì đối tượng Something sẽ bị dọn đi và trước khi nó bị dọn thì method finalize của nó được gọi, kết quả là câu "Đây là lời của tôi trước khi vĩnh biệt" được in ra.

    Còn nếu không có dòng strong=null thì đối tượng Something được tạo ra vẫn còn có strong reference dẫn đến nó (nghĩa là nó là strongly reachable object), nên theo tính chất của strong reference,khi đề nghị Garbage Collector dọn dẹp bằng cách gọi lệnh System.gc(), Garbage Collector sẽ KHÔNG dọn dẹp nó, vì vậy câu "Đây là lời của tôi trước khi vĩnh biệt" không được in ra.
    Lưu ý: Khi chương trình kết thúc thì chưa chắc method finalize đã được gọi, để chỉ định cho JVM việc này thì cần câu lệnh sau:

    Mã:
    System.runFinalizersOnExit(true);
    Ví dụ 2:

    Mã:
    package refdemo;public class StrongRefDemo {    public static class Something {        protected void finalize() {            System.out.println("Đây là lời của tôi trước khi vĩnh biệt");        }    }        private static void test() {        Something strong = new Something();         }     public static void main(String args[]) throws InterruptedException {        test();        System.gc();        Thread.sleep(5000);        System.out.println("Mọi thứ kết thúc");    }}
    Giải thích: Tương tự như ví dụ 1, sau khi kết thúc method test(), tham chiếu đến đối tượng Something bị mất (vì là biến cục bộ), cho nên đối tượng đủ điều kiện để Garbage Collector dọn dẹp, dòng chữ "Đây là lời của tôi trước khi vĩnh biệt" được in ra.
    Nhưng nếu ta sửa lại code, khai báo strong là biến của class như dưới đây thì khi kết thúc method test(), tham chiếu đến đối tượng Something chưa mất, cho nên chưa đủ điều kiện để Garbage Collector dọn dẹp đối tượng và kết quả là dòng chữ "Đây là lời của tôi trước khi vĩnh biệt" KHÔNG được in ra .

    Mã:
    package refdemo; public class StrongRefDemo {    static Something strong;    public static class Something {        protected void finalize() {            System.out.println("Đây là lời của tôi trước khi vĩnh biệt");        }    }        private static void test() {         strong = new Something();          }     public static void main(String args[]) throws InterruptedException {        test();        System.gc();        Thread.sleep(5000);        System.out.println("Mọi thứ kết thúc");    }}
    Và cũng tương tự như ví dụ 1, nếu ta thêm strong = null dưới đây thì câu "Đây là lời của tôi trước khi vĩnh biệt" sẽ được in ra:


    Mã:
    package refdemo; public class StrongRefDemo {    static Something strong;    public static class Something {        protected void finalize() {            System.out.println("Đây là lời của tôi trước khi vĩnh biệt");        }    }        private static void test() {         strong = new Something();          }     public static void main(String args[]) throws InterruptedException {        test();        strong=null;        System.gc();        Thread.sleep(5000);        System.out.println("Mọi thứ kết thúc");    }}
    Hoặc ta có thể không dùng strong = null mà ta tạo 1 đối tượng khác và tham chiếu đến nó như dưới đây thì dòng chữ "Đây là lời của tôi trước khi vĩnh biệt" cũng được in ra.


    Mã:
    package refdemo; public class StrongRefDemo {    static Something strong;    public static class Something {        protected void finalize() {            System.out.println("Đây là lời của tôi trước khi vĩnh biệt");        }    }        private static void test() {         strong = new Something();          }     public static void main(String args[]) throws InterruptedException {        test();        strong=new Something();        System.gc();        Thread.sleep(5000);        System.out.println("Mọi thứ kết thúc");    }}
    Ví dụ 3:
    Ta sửa code ở ví dụ 1 thành như sau (trước khi cho strong = null ta cho đối tượng vào 1 list):

    Mã:
    package refdemo; import java.util.ArrayList;import java.util.List; public class StrongRefDemo {    public static class Something {        protected void finalize() {            System.out.println("Đây là lời của tôi trước khi vĩnh biệt");        }    }     public static void main(String args[]) throws InterruptedException {        Something strong = new Something();        List<Something> list = new ArrayList<Something>();        list.add(strong);        strong=null;        System.gc();        Thread.sleep(5000);        System.out.println("Mọi thứ kết thúc");    }}
    Giải thích:
    Nhờ ta cho đối tượng Something vào list nên dù sau đó ta cho strong = null thì nó vẫn là strongly reachable object nên không bị Garbage Collector dọn dẹp, kết quả là KHÔNG in ra dòng chữ "Đây là lời của tôi trước khi vĩnh biệt"
    Còn nếu ta thêm dòng list = null như sau thì dòng chữ "Đây là lời của tôi trước khi vĩnh biệt" sẽ được in ra bởi vì đối tượng something khi đó hoàn toàn bị cô lập.


    Mã:
    package refdemo; import java.util.ArrayList;import java.util.List; public class StrongRefDemo {    public static class Something {        protected void finalize() {            System.out.println("Đây là lời của tôi trước khi vĩnh biệt");        }    }     public static void main(String args[]) throws InterruptedException {        Something strong = new Something();        List<Something> list = new ArrayList<Something>();        list.add(strong);        strong=null;        list=null;        System.gc();        Thread.sleep(5000);        System.out.println("Mọi thứ kết thúc");    }}
    Ta cũng có thể không cho list = null mà xóa list như dưới đây, cũng được kết quả tương tự như trên, dòng chữ "Đây là lời của tôi trước khi vĩnh biệt" được in ra.

    Mã:
    package refdemo; import java.util.ArrayList;import java.util.List; public class StrongRefDemo {    public static class Something {        protected void finalize() {            System.out.println("Đây là lời của tôi trước khi vĩnh biệt");        }    }     public static void main(String args[]) throws InterruptedException {        Something strong = new Something();        List<Something> list = new ArrayList<Something>();        list.add(strong);        strong=null;        list.clear();        System.gc();        Thread.sleep(5000);        System.out.println("Mọi thứ kết thúc");    }}
    Ví dụ 4:
    Tương tự như ví dụ 3, ta sửa lại ví dụ 1 như sau (trước khi cho strong=null thì cho anotherStrong tham chiếu đến đối tượng):

    Mã:
    package refdemo; public class StrongRefDemo {    public static class Something {        protected void finalize() {            System.out.println("Đây là lời của tôi trước khi vĩnh biệt");        }    }     public static void main(String args[]) throws InterruptedException {        Something strong = new Something();        Something anotherStrong=strong;        strong=null;        System.gc();        Thread.sleep(5000);        System.out.println("Mọi thứ kết thúc");    }}
    Kết quả chắc bạn đọc tự biết.
    (còn tiếp)</font>

  2. #2
    Cảm ơn bạn, bài đọc chi tiết lắm [IMG]images/smilies/applause.gif[/IMG] Mong bạn sớm viết tiếp, và đề cập sâu hơn về thứ tự ưu tiên GC sẽ dọn dẹp

  3. #3
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Trong Android chúng ta thấy thường xử dụng 2 loại chính là:
    -Soft reference (tạm dịch: tham chiếu mềm).
    -Weak reference (tạm dịch: tham chiếu yếu).

    Mọi người thử ngẫm tại sao?

 

 

Quyền viết bài

  • Bạn Không thể gửi Chủ đề mới
  • Bạn Không thể Gửi trả lời
  • Bạn Không thể Gửi file đính kèm
  • Bạn Không thể Sửa bài viết của mình
  •