AFAIK, đặc tả JVM (viết bằng tiếng Anh) không đề cập đến khi chính xác một đối tượng (hoặc một giá trị) nên bị xóa và để lại cho việc thực hiện (tương tự như vậy đối với R5RS ). Nó bằng cách nào đó yêu cầu hoặc đề xuất một trình thu gom rác nhưng để lại các chi tiết để thực hiện. Và tương tự như vậy đối với đặc tả Java.
Hãy nhớ rằng ngôn ngữ lập trình là thông số kỹ thuật (về cú pháp , ngữ nghĩa , v.v ...), không phải triển khai phần mềm. Một ngôn ngữ như Java (hoặc JVM của nó) có nhiều triển khai. Đặc điểm kỹ thuật của nó được xuất bản , có thể tải xuống (vì vậy bạn có thể nghiên cứu nó) và viết bằng tiếng Anh. §2,5.3 Heap của đặc tả JVM đề cập đến trình thu gom rác:
Lưu trữ heap cho các đối tượng được thu hồi bởi một hệ thống quản lý lưu trữ tự động (được gọi là bộ thu gom rác); các đối tượng không bao giờ được giải quyết rõ ràng. Máy ảo Java giả định không có loại hệ thống quản lý lưu trữ tự động cụ thể nào
(nhấn mạnh là của tôi; quyết toán BTW được đề cập trong §12.6 của thông số Java và một mô hình bộ nhớ nằm trong §17.4 của thông số Java)
Vì vậy (trong Java) bạn không nên quan tâm khi một đối tượng bị xóa và bạn có thể viết mã như - nếu điều đó không xảy ra (bằng cách suy luận một cách trừu tượng trong đó bạn bỏ qua điều đó). Tất nhiên bạn cần quan tâm đến việc tiêu thụ bộ nhớ và tập hợp các đối tượng sống, đó là một câu hỏi khác nhau . Trong một số trường hợp đơn giản (nghĩ về chương trình "xin chào thế giới"), bạn có thể chứng minh - hoặc tự thuyết phục bản thân - rằng bộ nhớ được phân bổ khá nhỏ (ví dụ: ít hơn một gigabyte), và sau đó bạn không quan tâm xóa các đối tượng riêng lẻ . Trong nhiều trường hợp hơn, bạn có thể thuyết phục bản thân rằng các vật thể sống(hoặc những người có thể tiếp cận, là một siêu thay đổi - lý do hơn là về những người sống) không bao giờ vượt quá giới hạn hợp lý (và sau đó bạn dựa vào GC, nhưng bạn không quan tâm đến việc thu gom rác diễn ra như thế nào và khi nào). Đọc về sự phức tạp không gian .
Tôi đoán rằng trên một số triển khai JVM chạy chương trình Java có thời gian ngắn như thế giới xin chào, trình thu gom rác hoàn toàn không được kích hoạt và không xảy ra xóa. AFAIU, một hành vi như vậy phù hợp với nhiều thông số kỹ thuật Java.
Hầu hết các triển khai JVM sử dụng các kỹ thuật sao chép thế hệ (ít nhất là đối với hầu hết các đối tượng Java, những đối tượng không sử dụng hoàn thiện hoặc tham chiếu yếu ; và hoàn thiện không được đảm bảo xảy ra trong một thời gian ngắn và có thể bị hoãn lại, vì vậy đây chỉ là một tính năng hữu ích mà mã của bạn không nên phụ thuộc nhiều vào) trong đó khái niệm xóa một đối tượng riêng lẻ không có ý nghĩa gì (vì một khối lớn các vùng nhớ chứa bộ nhớ cho nhiều đối tượng-, có thể vài megabyte cùng một lúc, được giải phóng cùng một lúc).
Nếu đặc tả JVM yêu cầu mỗi đối tượng phải được xóa chính xác càng sớm càng tốt (hoặc đơn giản là đặt nhiều ràng buộc hơn vào việc xóa đối tượng), các kỹ thuật GC thế hệ hiệu quả sẽ bị cấm và các nhà thiết kế Java và JVM đã khôn ngoan tránh điều đó.
BTW, có thể là một JVM ngây thơ không bao giờ xóa các đối tượng và không giải phóng bộ nhớ có thể phù hợp với thông số kỹ thuật (chữ cái, không phải tinh thần) và chắc chắn có thể chạy một điều thế giới xin chào trong thực tế (chú ý rằng hầu hết các chương trình Java nhỏ và ngắn có lẽ không phân bổ nhiều hơn một vài gigabyte bộ nhớ). Tất nhiên một JVM như vậy không đáng để đề cập và chỉ là một thứ đồ chơi (giống như việc triển khai nàymalloc
cho C). Xem Epsilon NoOp GC để biết thêm. Các JVM ngoài đời thực là những phần mềm rất phức tạp và trộn lẫn một số kỹ thuật thu gom rác.
Ngoài ra, Java không giống như JVM và bạn có các triển khai Java đang chạy mà không có JVM (ví dụ: các trình biên dịch Java trước thời hạn , thời gian chạy Android ). Trong một số trường hợp (chủ yếu là học thuật), bạn có thể tưởng tượng (được gọi là kỹ thuật "thu gom rác thời gian biên dịch") rằng chương trình Java không phân bổ hoặc xóa trong thời gian chạy (ví dụ: vì trình biên dịch tối ưu hóa đủ thông minh để chỉ sử dụng gọi ngăn xếp và biến tự động ).
Tại sao các đối tượng Java không bị xóa ngay lập tức sau khi chúng không còn được tham chiếu?
Bởi vì các đặc tả Java và JVM không yêu cầu điều đó.
Đọc cẩm nang GC để biết thêm (và thông số JVM ). Lưu ý rằng việc tồn tại (hoặc hữu ích cho tính toán trong tương lai) cho một đối tượng là thuộc tính toàn chương trình (không phải mô-đun).
Objective-C ủng hộ cách tiếp cận đếm tham chiếu đến quản lý bộ nhớ . Và điều đó cũng có những cạm bẫy (ví dụ, lập trình viên Objective-C phải quan tâm đến các tham chiếu vòng tròn bằng cách khám phá các tham chiếu yếu, nhưng một JVM xử lý các tham chiếu vòng tròn độc đáo trong thực tế mà không cần sự chú ý từ lập trình viên Java).
Không có Silver Bullet trong lập trình và thiết kế ngôn ngữ lập trình (lưu ý vấn đề Ngừng ; nói chung là một đối tượng sống hữu ích là không thể giải quyết được ).
Bạn cũng có thể đọc SICP , Lập trình ngôn ngữ lập trình , Sách rồng , Lisp trong các mảnh nhỏ và hệ điều hành: Ba mảnh dễ dàng . Chúng không phải là về Java, nhưng chúng sẽ mở mang đầu óc của bạn và sẽ giúp hiểu được JVM nên làm gì và nó có thể hoạt động như thế nào (với các phần khác) trên máy tính của bạn. Bạn cũng có thể dành nhiều tháng (hoặc vài năm) để nghiên cứu mã nguồn phức tạp của các triển khai JVM nguồn mở hiện có (như OpenJDK , có vài triệu dòng mã nguồn).