2012-01-19 28 views
6

Xin chào tất cả khi viết một danh sách mảng thực hiện, tôi hiểu điều quan trọng là đặt Item(x) thành vô giá trị khi nó bị xóa (thay vì chỉ đơn giản là quantity -= 1) để tránh rò rỉ bộ nhớ.Các mảng nguyên thủy "khác không" có yêu cầu nhiều bộ nhớ hơn không?

Tuy nhiên, nếu danh sách mảng của tôi là danh sách mảng int nguyên thủy (được hỗ trợ bởi int[]), bạn có nên đặt thành 0 không?

Similary, cho danh sách mảng các ký tự nguyên thủy (được hỗ trợ bởi char[]), khi RemoveRange() được gọi, có ý nghĩa khi điền vào dải đó với \u0000 không? Hoặc là nó hoàn toàn tốt đẹp chỉ cần cập nhật các length và con trỏ mà không sửa đổi mảng sao lưu?

là một mảng của ints điền với số không thể ít bộ nhớ chiếm hơn một mảng chiều dài bằng nhau đầy giá trị số nguyên vì thời gian chạy có thể làm cho tối ưu hóa?

+0

Nếu tôi nhớ chính xác, câu trả lời cho điều này là vô lý một chút. Tôi sẽ để ai đó thông minh hơn để giải thích chỉ vì bộ nhớ của tôi quá mơ hồ về chủ đề này. – Esko

+0

Rất cám dỗ để xác nhận sai rằng int [] nhận được số lượng lớn hơn số người nắm giữ lớn hơn. Do một số người không có mô hình về cách một máy tính hoạt động ở tất cả? – Ingo

+0

@ Tôi đã nghĩ rằng tối ưu hóa có thể được thực hiện nếu chúng có cùng giá trị (ví dụ: 0) – Pacerier

Trả lời

7

Có phải một mảng các số nguyên được điền bằng số không có thể chiếm ít bộ nhớ hơn một mảng có độ dài bằng với các giá trị số nguyên không?

Giả sử trong cả hai trường hợp, chúng tôi đang xử lý một số int[] - không. Hai mảng cùng loại và cùng độ dài sẽ luôn chiếm cùng một lượng bộ nhớ.

Không có cần để ghi đè lên các phần tử mảng "bây giờ trống" của bạn bằng 0. Nó sẽ không gây hại (ngoài lợi ích hiệu suất nhỏ) và thậm chí có thể làm mọi việc đơn giản hơn khi gỡ lỗi, nhưng bạn không cần để.

1

Không, không cần phải làm như vậy với các kiểu nguyên thủy (nghĩa là đặt chúng thành 0) vì lý do duy nhất "khe" được loại bỏ một cách rõ ràng là ngăn chặn các tham chiếu giả mạo với chúng.

1

Bạn không thể có ArrayList<int> cũng như bất kỳ loại vùng chứa nào khác với nguyên thủy. Về mảng đồng bằng, xem Jon Skeets trả lời.

+1

Tôi khá chắc chắn rằng anh ấy biết điều đó và muốn tạo lớp 'ArrayList' không chung chung của riêng mình như' IntArrayList'. –

+0

+ Sanjay - Tôi không chắc lắm. Dù sao, tôi không phải trả lời những gì ai đó có thể có thể có nghĩa là, nhưng để trả lời những gì anh ta đã hỏi. – Ingo

+1

Tôi đọc nó khi anh ta đang triển khai danh sách mảng của riêng mình (không sử dụng ArrayList). – wmorrison365

1

Nguyên thủy và tham chiếu luôn chiếm cùng một không gian.

2

... khi viết một thực hiện array list, tôi hiểu điều quan trọng là để thiết lập Item(x) để null khi nó được lấy ra (thay vì chỉ đơn giản là quantity -= 1) để ngăn chặn rò rỉ bộ nhớ.

Điều này không đúng. Đặt biến thành null không phải là thứ luôn cần thiết và không làm như vậy không có nghĩa là bạn bị rò rỉ bộ nhớ.

Tuy nhiên, nếu danh sách mảng của tôi là danh sách mảng int nguyên thủy, có ý nghĩa khi đặt thành 0 không?

Không, đối với nguyên thủy không quan trọng chút nào, 0 hoặc \u0000 (đối với char) chỉ là giá trị giống như bất kỳ giá trị nào khác. Nó không chiếm ít không gian hơn.

+1

Nó * là * cần thiết nếu bạn đang thực hiện một loại 'ArrayList' giống như mặc dù. Nếu tôi thêm một mục và sau đó loại bỏ phần tử đó khỏi danh sách, tôi không muốn tham chiếu đó được treo trong danh sách vì không có lý do gì. –

+0

Nếu bạn đang quản lý bộ nhớ của riêng mình thì bạn phải quản lý các đối tượng vô hiệu hóa không được sử dụng. Nếu không thì GC chọn nó nếu không có thêm refs cho đối tượng đó (tại một số thời gian không xác định). – wmorrison365

+1

@JonSkeet Có, đó có thể là một ý tưởng hay nếu bạn đang triển khai 'Danh sách' của riêng bạn. Nhiều người nghĩ rằng việc thiết lập các biến thành 'null' nói chung là một ý tưởng hay (không hiểu chính xác tại sao). Theo tôi, bạn không nên làm những điều chỉ vì bạn có một ý tưởng mơ hồ rằng nó là "tốt" - chỉ làm điều đó nếu bạn hiểu tại sao. – Jesper

1

Không, bạn cần phải vô hiệu hóa vùng đối tượng trong mảng để tránh rò rỉ. Nếu đối tượng vẫn được tham chiếu bởi mảng của bạn thì nó không thể là GC'd - do đó bạn bị rò rỉ.

Mặt khác, mặt khác, được phân bổ trên ngăn xếp, không phải đống, vì vậy không phải GC. Các primitives là các instance của các lớp được lưu trữ như các trường của đối tượng liên quan và được dọn sạch khi đối tượng là GC'd.

Ngoài ra, JLS cho biết rằng kích thước của nguyên thủy là VM cụ thể nhưng hầu hết (tất cả?) VM hiện hỗ trợ 4byte ints. Xem JLS để biết thêm thông tin:

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