JavaRush /Blog Java /Random-VI /Vòng đời của đối tượng

Vòng đời của đối tượng

Xuất bản trong nhóm
Xin chào! Tôi nghĩ bạn sẽ không quá ngạc nhiên nếu chúng tôi nói với bạn rằng kích thước bộ nhớ trên máy tính của bạn là có hạn :) Ngay cả một ổ cứng, lớn hơn RAM gấp nhiều lần, cũng có thể chứa đầy dung lượng với các trò chơi, phim truyền hình yêu thích của bạn, và như thế. Để ngăn điều này xảy ra, bạn cần theo dõi trạng thái hiện tại của bộ nhớ và xóa các tệp không cần thiết khỏi máy tính của mình. Lập trình Java có liên quan gì đến tất cả những điều này? Trực tiếp! Rốt cuộc, khi bất kỳ đối tượng nào được tạo bởi máy Java, bộ nhớ sẽ được cấp cho nó. Trong một chương trình lớn thực sự, hàng chục và hàng trăm nghìn đối tượng được tạo ra, mỗi đối tượng được phân bổ một phần bộ nhớ riêng. Vòng đời của đối tượng - 1Nhưng bạn nghĩ tất cả những đồ vật này tồn tại được bao lâu? Họ có “sống” trong suốt thời gian chương trình của chúng tôi đang chạy không? Dĩ nhiên là không. Với tất cả những ưu điểm của các đối tượng Java, chúng không phải là bất tử :) Các đối tượng có vòng đời riêng. Hôm nay chúng ta sẽ tạm dừng việc viết mã và xem xét quá trình này :) Hơn nữa, việc hiểu hoạt động của chương trình và quản lý tài nguyên là rất quan trọng. Vậy, sự sống của một vật thể bắt đầu từ đâu? Giống như một người - từ khi sinh ra, tức là được tạo ra.
Cat cat = new Cat();//вот сейчас и начался vital цикл нашего an object Cat!
Đầu tiên, Máy ảo Java phân bổ lượng bộ nhớ cần thiết để tạo đối tượng. Sau đó, cô ấy tạo một liên kết đến nó, trong trường hợp của chúng tôi - catđể có thể theo dõi nó. Sau đó, tất cả các biến được khởi tạo, hàm tạo được gọi, và lạ thay, đối tượng mới của chúng ta đã có cuộc sống riêng của nó :) Tuổi thọ của các đối tượng là khác nhau, không có con số chính xác ở đây. Trong mọi trường hợp, đôi khi nó tồn tại bên trong chương trình và thực hiện các chức năng của nó. Nói chính xác, một đối tượng là “sống” miễn là có các tham chiếu đến nó. Ngay khi không còn liên kết nào, đối tượng sẽ "chết". Ví dụ:
public class Car {

   String model;

   public Car(String model) {
       this.model = model;
   }

   public static void main(String[] args) {
       Car lamborghini  = new Car("Lamborghini Diablo");
       lamborghini = null;

   }

}
Trong phương pháp này, main()đối tượng xe Lamborghini Diablo không còn tồn tại ở dòng thứ hai. Chỉ có một liên kết đến nó và bây giờ liên kết này đã được chỉ định null. Vì không còn tài liệu tham khảo nào về Lamborghini Diablo nên nó trở thành "thứ rác rưởi". Không cần thiết phải thiết lập lại liên kết:
public class Car {

   String model;

   public Car(String model) {
       this.model = model;
   }

   public static void main(String[] args) {
       Car lamborghini  = new Car("Lamborghini Diablo");

       Car lamborghiniGallardo = new Car("Lamborghini Gallardo");
       lamborghini = lamborghiniGallardo;
   }

}
Ở đây chúng tôi đã tạo đối tượng thứ hai, sau đó chúng tôi lấy tham chiếu lamborghinivà gán nó cho đối tượng mới này. Hiện tại có Lamborghini Gallardohai tham chiếu đến đối tượng nhưng Lamborghini Diablokhông có tham chiếu nào đến đối tượng. Do đó đối tượng Diablotrở thành rác. Và tại thời điểm này, cơ chế Java tích hợp được gọi là trình thu gom rác, hay nói cách khác - Garbage Collector, GC, đi vào hoạt động.
Vòng đời của đối tượng - 2
Trình thu gom rác là một cơ chế Java nội bộ chịu trách nhiệm giải phóng bộ nhớ, nghĩa là loại bỏ các đối tượng không cần thiết khỏi bộ nhớ. Không phải vô cớ mà chúng tôi chọn bức tranh có robot hút bụi để khắc họa. Xét cho cùng, trình thu gom rác hoạt động theo cách tương tự: ở chế độ nền, nó “di chuyển” qua chương trình của bạn, thu thập rác và đồng thời bạn thực tế không tương tác với nó. Công việc của nó là loại bỏ những đối tượng không còn được sử dụng trong chương trình. Vì vậy, nó giải phóng bộ nhớ trong máy tính cho các đối tượng khác. Bạn có nhớ ở đầu bài giảng chúng ta đã nói rằng trong cuộc sống bình thường bạn phải theo dõi trạng thái của máy tính và xóa các tập tin cũ không? Vì vậy, trong trường hợp các đối tượng Java, trình thu gom rác sẽ thực hiện việc này cho bạn. Garbage Collector được khởi chạy nhiều lần trong quá trình vận hành chương trình của bạn: nó không cần được gọi cụ thể và đưa ra lệnh, mặc dù điều này có thể thực hiện được về mặt kỹ thuật. Sau này chúng ta sẽ nói nhiều hơn về nó và phân tích quá trình hoạt động của nó chi tiết hơn. Tại thời điểm trình thu gom rác tiếp cận đối tượng, ngay trước khi nó bị phá hủy, một phương thức đặc biệt sẽ được gọi trên đối tượng - finalize(). Nó có thể được sử dụng để giải phóng một số tài nguyên bổ sung mà đối tượng đang sử dụng. Phương thức này finalize()thuộc về lớp Object. Nghĩa là, cùng với equals(), hashCode()toString(), mà bạn đã gặp trước đó, bất kỳ đối tượng nào cũng có nó. Sự khác biệt của nó so với các phương pháp khác là nó... nói thế nào nhỉ... rất thất thường. Cụ thể, nó không phải lúc nào cũng được gọi trước khi phá hủy một đối tượng. Lập trình là một điều chính xác. Lập trình viên ra lệnh cho máy tính làm điều gì đó và máy tính sẽ thực hiện việc đó. Có thể bạn đã quen với hành vi này và ban đầu bạn có thể khó chấp nhận ý tưởng này: “Trước khi các đối tượng bị hủy, phương thức finalize()lớp được gọi Object. Hoặc nó không được gọi. Nếu chúng ta gặp may mắn!” Tuy nhiên, điều này là đúng. Bản thân máy Java sẽ xác định có nên gọi phương thức finalize()trong từng trường hợp cụ thể hay không. Ví dụ: hãy thử chạy đoạn mã sau để thử nghiệm:
public class Cat {

   private String name;

   public Cat(String name) {
       this.name = name;
   }

   public Cat() {
   }

   public static void main(String[] args) throws Throwable {

       for (int i = 0 ; i < 1000000; i++) {

           Cat cat = new Cat();
           cat = null;//вот здесь первый an object становится доступен сборщику мусора
       }
   }

   @Override
   protected void finalize() throws Throwable {
       System.out.println("Объект Cat уничтожен!");
   }
}
Chúng tôi tạo một đối tượng Catvà trong dòng mã tiếp theo, chúng tôi đặt lại tham chiếu duy nhất đến nó. Và như vậy - một triệu lần. Chúng tôi đã ghi đè phương thức một cách rõ ràng finalize()và nó sẽ in chuỗi đó ra bàn điều khiển một triệu lần, mỗi lần trước khi hủy đối tượng Cat. Nhưng không! Nói chính xác thì nó chỉ chạy được 37.346 lần trên máy tính của tôi! Nghĩa là, chỉ có 1 trong số 27 trường hợp máy Java mà tôi đã cài đặt quyết định gọi một phương thức finalize()- trong các trường hợp khác, việc thu gom rác được tiến hành mà không có điều này. Hãy thử tự chạy mã này: rất có thể kết quả sẽ khác. Như bạn có thể thấy, finalize()thật khó để gọi đó là một đối tác đáng tin cậy :) Do đó, một lời khuyên nhỏ cho tương lai: bạn không nên dựa vào phương pháp này finalize()trong trường hợp giải phóng một số tài nguyên quan trọng. Có thể JVM sẽ gọi nó, có thể không. Ai biết? Nếu trong suốt thời gian tồn tại, đối tượng của bạn chiếm một số tài nguyên cực kỳ quan trọng đối với hiệu suất, chẳng hạn như nó giữ kết nối mở với cơ sở dữ liệu, thì tốt hơn là tạo một phương thức đặc biệt trong lớp của bạn để giải phóng chúng và gọi nó một cách rõ ràng khi đối tượng không cần nữa. Bằng cách này, bạn sẽ biết chắc chắn rằng hiệu suất chương trình của bạn sẽ không bị ảnh hưởng. Ngay từ đầu, chúng tôi đã nói rằng việc quản lý bộ nhớ và loại bỏ rác là rất quan trọng và điều này đúng. Việc xử lý tài nguyên không phù hợp và thiếu hiểu biết về quá trình tập hợp các đối tượng không cần thiết có thể dẫn đến rò rỉ bộ nhớ. Đây là một trong những lỗi lập trình nổi tiếng nhất. Mã được lập trình viên viết không chính xác có thể dẫn đến việc bộ nhớ mới được phân bổ mỗi lần cho các đối tượng mới được tạo, trong khi các đối tượng cũ, không cần thiết không có sẵn để bộ thu gom rác loại bỏ. Vì chúng ta đã so sánh với robot hút bụi, hãy tưởng tượng điều gì sẽ xảy ra nếu trước khi khởi động robot, bạn rải tất khắp nhà, làm vỡ một chiếc bình thủy tinh và để lại một bộ Lego đã tháo rời trên sàn. Tất nhiên, robot sẽ cố gắng làm điều gì đó nhưng đến một lúc nào đó nó sẽ bị kẹt.
Vòng đời của đối tượng - 3
Để nó hoạt động bình thường, bạn cần giữ sàn ở tình trạng tốt và loại bỏ mọi thứ mà máy hút bụi không thể xử lý được. Bộ thu gom rác hoạt động theo nguyên tắc tương tự. Nếu có nhiều đồ vật còn lại trong chương trình mà nó không thể thu thập được (chẳng hạn như một chiếc tất hoặc Lego dành cho robot hút bụi), thì đến một lúc nào đó bộ nhớ sẽ hết. Và không chỉ chương trình bạn viết sẽ bị treo mà tất cả các chương trình khác đang chạy trên máy tính tại thời điểm đó cũng sẽ bị treo. Sẽ không có đủ bộ nhớ cho họ. Đây là vòng đời của đối tượng và trình thu gom rác trong Java. Không cần phải ghi nhớ điều này: bạn chỉ cần hiểu nguyên lý hoạt động. Trong bài giảng tiếp theo, chúng ta sẽ nói về các quy trình này chi tiết hơn, nhưng bây giờ bạn có thể quay lại giải quyết các vấn đề về JavaRush :) Chúc may mắn!
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION