Tôi nghe tài sản thanh lịch nhất của java là Garbage Collection Tôi muốn biết nó có đảm bảo rằng một chương trình sẽ không hết bộ nhớ?Việc thu gom rác có đảm bảo rằng một chương trình sẽ không hết bộ nhớ?
Trả lời
Không, nó không đảm bảo điều này. Nó là hoàn toàn có thể cho một lập trình viên nhầm lẫn tạo ra các đối tượng mà không bao giờ đi ra khỏi phạm vi, do đó tiêu thụ nhiều hơn và nhiều hơn nữa bộ nhớ cho đến khi tất cả heap là kiệt sức.
Trách nhiệm của người lập trình là đảm bảo rằng các đối tượng không còn được sử dụng không còn được tham chiếu bởi ứng dụng. Bằng cách đó, người thu gom rác có thể thực hiện công việc của mình và thu hồi bộ nhớ được sử dụng bởi các đối tượng này.
Ví dụ
public class Main {
public static void main(String[] main) {
List<String> l = new LinkedList<String>();
// Enter infinite loop which will add a String to
// the list: l on each iteration.
do {
l.add(new String("Hello, World"));
} while(true);
}
}
số Nếu bạn xây dựng rất nhiều các đối tượng (triệu) và giữ một tham chiếu đến họ để họ không đi ra khỏi phạm vi (ví dụ bằng cách thêm chúng vào một ArrayList), bạn có thể hết bộ nhớ địa chỉ.
Không, vẫn còn nhiều cách để hết bộ nhớ. Bộ thu gom rác chỉ có thể lấy lại bộ nhớ cho các đối tượng không còn được tham chiếu nữa - điều đó tùy thuộc vào bạn để đảm bảo rằng bạn không tham chiếu các đối tượng bạn không cần hoặc sử dụng Tham chiếu mềm cho các đối tượng bạn muốn có, nhưng không tâm trí biến mất nếu bộ nhớ bị chặt chẽ.
Không, bạn luôn có thể cố gắng cấp phát bộ nhớ nhiều hơn khả dụng.
Thu gom rác tự động chỉ có nghĩa là rác (tức là bộ nhớ không được thu nhận) sẽ tự động được thu thập (tức là, được khai hoang để sử dụng thêm). Nếu bạn giữ tham chiếu đến nó, nó không phải là rác, và không được thu thập.
Tuyệt đối không. Ngay cả trong một ngôn ngữ thu thập rác như Java, bạn có thể dễ dàng mất các tham chiếu, có nghĩa là các đối tượng sẽ không bao giờ bị thu gom rác.
Thậm chí sau đó, bạn có thể đơn giản khởi tạo (và giữ tham chiếu đến) quá nhiều đối tượng để hệ thống xử lý.
Làm thế nào có thể bất kỳ điều gì đảm bảo một chương trình không hết bộ nhớ để tự ý xóa một mục khỏi bộ nhớ để dành chỗ cho phân bổ mới?
Bây giờ, điều gì sẽ xảy ra nếu bạn thực sự giữ một tham chiếu về (sử dụng) thứ được chọn ngẫu nhiên để được loại bỏ? Bạn sẽ sớm có hành vi không chính xác.
Không. Bộ sưu tập rác chỉ bảo vệ chống lại một loại rò rỉ bộ nhớ. Cụ thể, loại xảy ra nếu bạn không giải phóng bộ nhớ một cách rõ ràng khi ứng dụng của bạn không còn cần đến nữa. Nếu ứng dụng của bạn giữ các tham chiếu đến các đối tượng không cần thiết (ví dụ: các Danh sách mai mai), trình thu gom rác không thể xóa chúng và ứng dụng của bạn vẫn có thể hết bộ nhớ.
Không, hoàn toàn không.
Trong các ngôn ngữ không thu thập rác, lập trình viên (hoặc thư viện mà anh ta sử dụng) chịu trách nhiệm đưa ra yêu cầu cho bộ nhớ và trả lại bộ nhớ được cấp cho "tái chế". không có đảm bảo rằng bộ nhớ sẽ có sẵn khi nó được yêu cầu. Tuy nhiên, nếu bạn không bao giờ rõ ràng "tái chế", có thể có trường hợp yêu cầu bị từ chối vì không có bộ nhớ, nhưng nếu bộ nhớ được tái chế thì khối đó có thể đã được trả lại cho yêu cầu này.
Việc thu thập rác tự động có nghĩa là hệ thống có thể tái chế cho bạn. Kết quả là, một số yêu cầu sẽ được lấp đầy bằng cách sử dụng bộ nhớ "tái chế". Tuy nhiên, như với các ngôn ngữ không phải GC, một số yêu cầu không thể được lấp đầy. Ví dụ, nếu hệ thống của bạn có 1000 khối có sẵn và bạn cần 1500 cùng một lúc, không GC nào trên thế giới sẽ giúp bạn vì không có gì thực sự có sẵn để tái chế.
Không, việc thu thập rác không thể đảm bảo rằng ứng dụng của bạn sẽ không hết bộ nhớ. Nó thậm chí sẽ không đảm bảo rằng ứng dụng của bạn sẽ không hết bộ nhớ khi bộ nhớ có sẵn. Nếu bạn đến gần hết bộ nhớ hoặc đang phân bổ nhiều đối tượng, nó có thể khiến GC bị thrash, ném ra một ngoại lệ bộ nhớ. Chương trình cũng có thể hết bộ nhớ khi nó đã sử dụng tất cả bộ nhớ vật lý (thực tế và ảo) hoặc chương trình vượt quá bộ nhớ tối đa cho phép bởi JVM (xem -Xmx).
No. Bộ thu gom rác, giúp bạn tự động giải phóng bộ nhớ không sử dụng.
Cách thức hoạt động là, nếu không thể liên lạc với đối tượng, bộ nhớ cho đối tượng đó có thể là rác được thu thập.
Ví dụ:
public void test() {
Object o = new Object();
// the memory used by o may be garbage collected after this line
}
Nhưng nếu bạn không bao giờ phát hành tài liệu tham khảo đối tượng, thu gom rác sẽ không bao giờ thu thập bất cứ điều gì và một OutOfMemoryError sẽ được ném ra.
List list = ....
public void test() {
o = new Object();
list.add(o);
// the memory used by o WON'T be garbage collected after this line
// because its reference is used in the list.
}
Nếu bạn sử dụng điều này nhiều lần:
while(true) {
test();
}
Danh sách này sẽ tiếp tục tăng trưởng vô thời hạn cho đến khi bạn chạy ra khỏi bộ nhớ
Để trả lời câu hỏi của bạn, NO
. Thu gom rác không đảm bảo rằng một chương trình sẽ không hết bộ nhớ.
- Xem xét đối tượng bạn không muốn sử dụng bất kỳ thứ gì khác giống như rác.
- Tham chiếu đến các đối tượng đó sẽ là giống như có rác trong nhà của bạn.
- Bộ sưu tập rác giống như xe tải chở rác của thị trấn thu gom rác.
- Nếu bạn sẽ không tiết lộ những tài liệu tham khảo , nó cũng giống như không dùng rác ra và chẳng mấy chốc ngôi nhà của bạn sẽ be qua đầy rác như kẻ xe tải rác sẽ không đưa ra rác từ ngôi nhà của bạn.
Đối tượng không được xử lý sẽ được thu gom rác tự động bởi bộ thu gom rác. Trong java, hầu hết các tham chiếu đến các đối tượng được phát hành tự động khi bạn thoát khỏi phương thức.
Đối tượng có tham chiếu đến các đối tượng khác, từ đó tham chiếu đến các đối tượng khác tạo đồ thị toàn bộ đối tượng. Vì vậy, như đối tượng như vậy có thể được tham chiếu bởi nhiều hơn một đối tượng.
- Nếu đối tượng không có tham chiếu bằng không, nó đủ điều kiện để thu gom rác thải .
- Đối tượng được phân bổ trên heap.
- Bộ thu gom rác chạy từ thời gian tới thời gian để xóa các đối tượng không được kiểm duyệt từ heap.
- Nếu bạn liên tục tạo nhiều đối tượng trên đống mà không giải phóng bạn sẽ cuối cùng có được
OutOfMemoryError
Ví dụ với thu gom rác thải tại nơi làm việc
public class TestGarbageNoError {
public static void main(String[] args) {
String hugeString;
for (int i = 0; i < Integer.MAX_VALUE; i++) {
System.out.println("i = " + i);
hugeString = getHugeString();
// At each iteration reference variable hugeString
// points to new String object. Hence there will be
// zero reference to previous string object and will
// eventually be garbage collected
}
}
public static String getHugeString() {
StringBuilder sb = new StringBuilder();
for (int x = 0; x < 5000000; x++) {
sb.append(x);
}
return sb.toString();
}
}
.
Ví dụ với bộ nhớ bị rò rỉ tại nơi làm việc
public class TestGarbageError {
public static void main(String[] args) {
Collection<String> memoryLeak = new ArrayList<String>();
for (int i = 0; i < Integer.MAX_VALUE; i++) {
System.out.println("i = " + i);
String hugeString = getHugeString();
memoryLeak.add(hugeString);
// At each iteration reference variable hugeString
// points to new String object. But all objects are added
// to memoryLeak Collection and will always have atleast one
// reference, i.e. from memoryLeak object. Hence this string
// objects will never be garbage collected and program will
// eventually run out of memory
}
}
public static String getHugeString() {
StringBuilder sb = new StringBuilder();
for (int x = 0; x < 5000000; x++) {
sb.append(x);
}
return sb.toString();
}
}
không hiểu nó, trong ví dụ thứ hai String được định nghĩa trong vòng lặp, do đó, với mỗi con trỏ lặp đang bị mất trên stack, có thể ghi đè bằng một cái mới (cách nhìn của tôi về cách mọi thứ đang diễn ra). Vui lòng giải thích những gì xảy ra trên mỗi lần lặp với đối tượng String này .... –
Bạn đã bỏ lỡ dòng "memoryLeak.add (hugeString);". Đây là nơi tham chiếu đến mọi chuỗi được duy trì do bộ nhớ bị rò rỉ. Hãy thử chạy cả hai chương trình, bạn sẽ thấy sự khác biệt trong kết quả. –
ahh ... vâng, bây giờ tôi đã thấy thêm dòng. Offcourse, nếu một nơi nào đó là mã memoryLeak.get (..), objetc phải giữ tham chiếu đến String. Tôi nghĩ rằng một cái gì đó đã được với nơi định nghĩa nơi String bigString được đặt ... –
Tuy nhiên, nó được đảm bảo rằng trước khi JVM tuyên bố OutOfMemoryException nó rác sẽ thu thập tất cả các tài liệu tham khảo phải thu và xem xét để sử dụng bộ nhớ bây giờ miễn phí.
- 1. Tại sao Ada không có bộ thu gom rác?
- 2. Java không thu thập bộ nhớ rác
- 3. Bộ thu gom rác có gọi là Dispose() không?
- 4. Có một JVM thiếu bộ thu gom rác không?
- 5. Có đảm bảo rằng bộ nhớ sẽ không ra các bit đệm trong cấu trúc không?
- 6. Thu gom rác trong Perl
- 7. đế và bộ thu gom rác Đi
- 8. tham chiếu nội bộ ngăn chặn việc thu gom rác
- 9. Lisp không có Bộ thu gom rác để lập trình mức thấp
- 10. Thu gom rác trễ?
- 11. Bộ thu gom rác sẽ thu thập các thói quen Go sẽ không bao giờ tiếp tục?
- 12. Các trường tĩnh có mở để thu gom rác không?
- 13. HĐH có thể ngừng quá trình Java từ việc thu gom rác thải không?
- 14. JRuby - Cách khởi động bộ thu gom rác?
- 15. Có phải rò rỉ bộ nhớ nếu bộ thu gom rác chạy bất thường?
- 16. Buộc thu gom rác của mảng, C#
- 17. Khi nào để thu gom rác
- 18. Bộ thu gom rác cho đa lõi llvm?
- 19. Có thể ngừng thu gom rác thải .NET không?
- 20. Tham khảo chéo và thu gom rác
- 21. Đối tượng COM này có bị thu gom rác không?
- 22. Tiêu chí để kích hoạt thu gom rác trong .Net
- 23. Buộc thu gom rác thải
- 24. Làm thế nào để đảm bảo thu gom rác của FutureTask được gửi đến ThreadPoolExecutor và sau đó bị hủy?
- 25. Thời gian thu gom rác cực dài
- 26. Khi nào bộ thu gom rác net hoạt động?
- 27. đa và thu gom rác thải
- 28. Thông báo Thu gom Rác Bỏ lỡ
- 29. Các loại giá trị có được thu gom rác không?
- 30. Bộ thu gom rác DalvikVM có ngăn chặn toàn bộ VM không?
Nếu thu thập rác có nghĩa là ứng dụng nhiều terabyte của tôi không bao giờ hết bộ nhớ, điều đó sẽ thực sự tuyệt vời để xử lý các tập dữ liệu lớn. –