2017-01-04 27 views
5

Người dùng tải lên một tập tin rất lớn bao gồm 1 triệu từ. Tôi phân tích cú pháp tệp và đặt từng dòng của tệp vào một LinkedHashMap<Integer, String>.LinkedHashMap bộ nhớ tiêu thụ

Tôi cần O (1) truy cập và xóa bằng khóa. Ngoài ra, tôi cần phải duy trì thứ tự truy cập, lặp lại từ bất kỳ vị trí và sắp xếp nào.

Bộ nhớ tiêu thụ là rất lớn. Tôi kích hoạt Strings deduplication feature xuất hiện trong Java 8, nhưng nó quay ra rằng LinkedHashMap tiêu thụ hầu hết các bộ nhớ.

Tôi thấy rằng LinkedHashMap.Entryconsumes 40 bytes, nhưng chỉ có 2 con trỏ - một cho mục nhập tiếp theo và một cho mục nhập trước đó. Tôi nghĩ 1 con trỏ phải là 64 bit hoặc 32 bit. Mua nếu tôi chia 409,405,320 (byte) cho 6.823,422 (số mục nhập) tôi có 60 byte cho mỗi mục nhập.

Tôi nghĩ rằng tôi không cần con trỏ trước đó, con trỏ tiếp theo phải đủ để giữ trật tự. Tại sao LinkedHashMap tiêu thụ quá nhiều bộ nhớ? Làm cách nào để giảm mức tiêu thụ bộ nhớ?

Instance occurence

+0

là nó có thể 'cái Integer' wrapper là sử dụng nhiều bộ nhớ thêm? Có thể triển khai ['int'-based] (https://github.com/ggrandes/kvstore/blob/master/src/main/java/org/javastack/kvstore/structures/hash/IntLinkedHashMap.java) có thể giúp – Moira

+1

@ 1blustone Nếu bạn nhìn vào hình ảnh, bạn có thể thấy rằng 'Integer' s chiếm 16% của đống. 'LinkedHashMap.Entry's đang chiếm nhiều hơn gấp 3 lần. Tôi tin rằng OP muốn biết lý do tại sao điều này xảy ra. – Michael

+1

Bạn quá nhanh khi duyệt các nguồn. mục nhập đó kế thừa từ 'HashMap.Node' có 4 trường khác và có thêm [tiêu đề đối tượng] (http://stackoverflow.com/q/26357186) có kích thước chỉ là chi tiết triển khai. – glee8e

Trả lời

1

Làm thế nào để giảm mức tiêu thụ bộ nhớ?

1) Thêm -XX:+UseCompressedOops cờ vào khởi động JVM của bạn.

2) Triển khai phiên bản LinkedHashMap của riêng bạn, được tối ưu hóa cho nhu cầu của bạn. I E. sử dụng nguyên thủy int làm khóa thay vì Integer, xóa con trỏ "trước" nếu bạn không cần nó, v.v. Lưu ý rằng sao chép nguồn OpenJDK có thể là không thể trừ khi bạn muốn phát hành bản đồ băm đã sửa đổi của mình theo giấy phép GPLv2, vì OpenJDK là GPLv2. Tuy nhiên, bạn có thể sao chép và sửa đổi thực hiện LinkedHashMap từ Dự án nguồn mở Android, bởi vì nó được Apache cấp phép.

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