2012-07-10 46 views
7

Vâng, tôi đã phát triển một ứng dụng java sử dụng một số mối quan hệ đối tượng làm cho việc sử dụng bộ nhớ quá đắt. Tôi không có kinh nghiệm quản lý bộ nhớ java vì thiết kế ứng dụng làm cho việc phá hủy các đối tượng trở nên khó khăn và sử dụng lại không gian đã bị xóa trước đó. Ví dụ, tôi đang sử dụng các mẫu Observer và MVC.Làm thế nào để tiêu diệt các đối tượng java?

Vì vậy, lý thuyết nói rằng ..

Một đối tượng trở nên đủ điều kiện để thu gom rác hoặc GC nếu nó không thể truy cập từ bất kỳ đề sống hay bất kỳ tài liệu tham khảo tĩnh

Nói cách khác bạn có thể nói rằng một đối tượng trở nên đủ điều kiện để thu thập rác nếu tất cả các tham chiếu của nó là null. Tuy nhiên, trong kinh nghiệm ngắn của tôi, quá khó để tôi phá hủy tất cả các tham chiếu từ các đối tượng mà tôi muốn xóa khỏi bộ nhớ (ví dụ: khi khung được đóng) khi bạn có kịch bản như của tôi, nơi bạn không Không biết có bao nhiêu tài liệu tham khảo cho các lớp của bạn tồn tại.

Theo ngữ cảnh này, làm thế nào tôi có thể đối phó với sự phá hủy đối tượng khi có nhiều tham chiếu đến nó? hoặc làm cách nào để quản lý bộ nhớ khi bạn có một tham chiếu phức tạp cho mỗi người khác?

Trả lời

17

Giữ Theo dõi

Theo bối cảnh này, làm thế nào tôi có thể đối phó với sự tàn phá đối tượng khi có bội số tham chiếu đến nó?

Bằng cách đảm bảo các tham chiếu này không cần thiết nữa.

Nếu bạn cô lập họ, thậm chí trong một đồ thị bị cô lập lớn của các đối tượng không sử dụng không kết nối được nữa để progam chính của bạn, sau đó họ đều đủ điều kiện để thu gom rác thải.

Biến cục bộ đã đạt đến cuối phạm vi của chúng sẽ đủ điều kiện thu thập rác (và các đối tượng được chứa của chúng), nếu chúng chưa được "liên kết" với bất kỳ thứ gì khác (được thêm vào bộ sưu tập, acposposite, v.v. ...). Đối với các đối tượng giao diện người dùng, điều này thực sự khó có thể giải thích về mặt đồ thị đối tượng, hãy đảm bảo vứt bỏ chúng một cách chính xác hoặc đọc tài liệu để đảm bảo rằng chúng sẽ được xử lý tự nhiên.

Simplified View of Reference Counting in the JVM

"Rời khỏi [GC] Một mình !!"

hoặc làm cách nào để quản lý bộ nhớ khi bạn có tham chiếu phức tạp với nhau?

Bạn không thể "quản lý" bộ nhớ. Bạn chỉ có thể quản lý tài liệu tham khảo. Ý tưởng là "nghiêm trọng" kết nối của bạn với các đối tượng của bạn bằng cách đơn giản là không có tham chiếu đến chúng. Sau đó họ sống trong bộ nhớ cho đến khi GC tiêu diệt chúng.

Không tìm cách gây rối với GC để buộc nó làm việc.Đó là một con quái vật khá thông minh, và khi bạn có thể thử để hướng dẫn nó để phản ứng với một số yêu cầu một cách rõ ràng - nó có thể phớt lờ bạn - đó là usually a bad idea: do not invoke the GC explicitly, tránh finalizers và explicit nullingif you don't understand their implications.


Lưu ý để trả lời bình luận của bạn

Đơn giản chỉ cần xóa mỡ một tham chiếu đến một đối tượng mà đã được thêm vào một vài bộ sưu tập hoặc composit sẽ không làm cho nó đủ điều kiện cho bộ sưu tập. Bằng cách này, you'd have only nulled one reference.

Bạn cần phải loại bỏ đối tượng này khỏi tất cả các danh sách hoặc vùng chứa có tham chiếu đến nó (về cơ bản, khiến chúng "quên" về đối tượng này). Một khi không có đối tượng nào vẫn còn "nhớ" hoặc có một "liên kết" tới đối tượng đã tạo của bạn, nó sẽ trở thành một mục cô đơn trong biểu đồ của Garbage Collector, làm cho nó trở thành một ứng cử viên để xóa.

Có thể nó có vẻ tẻ nhạt, nhưng nếu bạn nghĩ về ngôn ngữ mà bạn quản lý bộ nhớ theo cách thủ công (C hoặc C++, đặt tên cho 2 tham chiếu rõ ràng nhất), các con trỏ tự do và rỗng thực sự sẽ tiêu diệt chúng, nhưng bạn vẫn cần phải loại bỏ phần tử khỏi danh sách (hoặc bất kỳ vùng chứa nào) hoặc chúng sẽ xuất hiện như các thùng rỗng thành một con trỏ rỗng.


Tiếp tục đọc

+0

Đã hiểu! nhưng ... làm thế nào tôi có thể cô lập một đối tượng khi nó có thể được thêm vào (ví dụ) trong mảng bội số? Đặt 'object = null' sẽ xóa tất cả các tham chiếu? – manix

+1

@manix: không, nó sẽ không. mà sẽ chỉ null tham chiếu có tên 'object' trong phạm vi hiện tại. Bạn cần phải thực sự loại bỏ đối tượng này khỏi tất cả các danh sách này hoặc bất kỳ vùng chứa nào khác. – haylem

+0

@halem Có phải danh sách nhiều mảng ngắn hay dài không? Nếu họ sống ngắn, thì không có vấn đề gì cả. Sau khi danh sách không còn có thể truy cập được nữa, bộ thu gom rác sẽ làm việc phép thuật của nó. OTH nếu danh sách mảng tồn tại lâu, thì tất cả các phần tử của nó sẽ có thể truy cập được trong suốt cuộc đời của nó trừ khi bạn làm điều gì đó. Tôi đề nghị arraylists sống ngắn. – emory

6

Toàn bộ điểm thu gom rác java là bạn không phải làm gì cả. Thu gom rác được thực hiện cho bạn.

+0

Nuff nói lol. Ngoài ra, trong trường hợp của bạn, tôi thấy lý do tại sao bạn đang lo lắng. Nhưng hãy nghĩ về nó theo cách này, hoặc 2 kịch bản thực sự. 1, nhà phát triển đã tạo bất kỳ mã nào bạn đang sử dụng không ghi lại các rò rỉ bộ nhớ tiềm ẩn, trong trường hợp đó bạn không thể làm gì nhiều ngoại trừ sử dụng cái gì khác. 2, bạn đọc tài liệu giải thích điều này và giúp bạn tránh mọi vấn đề như bạn nói. SO thường không lo lắng về nó quá nhiều, trừ khi bạn nghi ngờ một số mã đang làm chậm ứng dụng của bạn. – Andy

+0

cách sử dụng phương thức "proxy" như @Martinsos cho biết? để loại bỏ các tham chiếu của nó – manix

1

Chỉ định mọi tham chiếu bạn muốn GC thu thập tới null.

+0

làm điều tương tự nếu obj chứa chạy đối tượng thread hoặc Timer? – suiwenfeng

1

Điều bạn có thể làm là tạo một lớp trung gian. Ví dụ, nếu bạn có thể hiện của lớp A, bạn có rất nhiều tài liệu tham khảo và bạn muốn loại bỏ nó nhưng rất nhiều tài liệu tham khảo gây khó khăn, bạn có thể thực hiện các bước sau: tạo cá thể lớp B không chứa gì khác hơn tham chiếu đến cá thể lớp A (giống như một loại proxy nào đó). Bây giờ bạn sẽ có rất nhiều tham chiếu đến thể hiện của lớp B nhưng chỉ một tham chiếu đến cá thể của lớp A, mà bạn có thể dễ dàng loại bỏ và bộ gom rác sẽ thu thập cá thể của lớp A.

Hình ảnh hiển thị sự khác biệt khi sử dụng proxy (ví dụ của lớp B): Bây giờ chỉ có một tham chiếu đã bị xóa.

enter image description here

+0

hữu ích! Bây giờ rõ ràng hơn :) – manix

0

Đối với hầu hết các phần, GC sẽ làm điều đó là kỳ diệu trong thời gian tốt.

Bạn có thể gặp tình huống theo đó, một chế độ xem đang quan sát một mô hình và bạn muốn bỏ chế độ xem nhưng giữ mô hình. Trong trường hợp đó, bạn sẽ cần phải nhớ các đối tượng gọi lại quan sát và loại bỏ chúng khi bạn hủy bỏ chế độ xem. Bạn không nhất thiết phải có các trường đặc biệt cho mỗi người quan sát - một tập hợp các nhiệm vụ hủy đăng ký một cuộc gọi lại sẽ được thực hiện tốt. Hoặc, phức tạp hơn, bạn có thể có một lớp của indirection thoáng qua trên mô hình mà unzips từ một trong những cơ bản. Tôi đề nghị tránh những thứ kỳ lạ với các tham chiếu yếu của một loại này hay cách khác.

Trong trường hợp bạn có thể có finalisers (hoặc yêu cầu một số loại bản đồ yếu đuổi), chẳng hạn như có lẽ với một java.awt.Frame, Bạn có thể muốn một lớp indirection giữa tài nguyên và bộ nhớ hog mà chỉ đơn giản là có thể được vô hiệu.

Các vấn đề liên quan