2012-10-25 22 views
8

Máy ảo Java cũng có thể sử dụng chiều rộng int-chiều rộng cho các trường short (điều này phụ thuộc vào việc triển khai nội bộ của chúng). Chỉ các mảng (short[]) là ngoại lệ, trong đó nó luôn được đảm bảo rằng chúng chiếm ít không gian hơn một số int[] trong nội bộ). Điều gì về Dalvik?Bộ nhớ cần thiết cho các trường 'ngắn' trong Dalvik?

Ví dụ: Tôi có một lớp học có 50 trường thuộc loại short. Đôi khi trong ứng dụng của tôi, 10000 trong số các lớp này tồn tại. Điều này có nghĩa là các trường short phải sử dụng 1MB bộ nhớ, nhưng nếu Dalvik sử dụng 4 byte cho giá trị short nội bộ, thì việc sử dụng bộ nhớ này sẽ là 2MB.

Tôi nên sử dụng bao nhiêu bộ nhớ để sử dụng Dalvik? (Điều này đề cập đến việc sử dụng bộ nhớ trong của nó, và tôi biết thực tế là nó có thể không được phản ánh bằng cách sử dụng bộ nhớ hệ thống, ví dụ như vì Dalvik đã dành một lượng bộ nhớ cao hơn từ hệ thống.)

+1

Đối với người dùng đã chuẩn bị chỉnh sửa (định dạng) cho bài đăng của tôi: cảm ơn. Thật không may, hệ thống đã không cho phép tôi chấp nhận nó, nó nói "chỉnh sửa đã bị từ chối". Vì vậy, theo như tôi có thể nhớ lại, tôi đã cố gắng áp dụng các chỉnh sửa của riêng mình. –

+0

"Các máy ảo Java được biết đến với việc sử dụng chiều rộng cỡ int cho các trường ngắn" bạn có thể sao lưu câu lệnh này với bất kỳ tham chiếu nào không? – kosa

+0

Tôi đã có một chút không chính xác ở đó, vì vậy tôi đã chỉnh sửa nó. Dưới đây là một số chủ đề liên quan đến stackoverflow: http://stackoverflow.com/questions/8855754/android-does-short-take-really-2-bytes http://stackoverflow.com/questions/1904857/which-is-better- to-use-short-or-int –

Trả lời

4

Trong dalvik, trường đôi và dài là 8 byte, mọi thứ khác (bao gồm cả ngắn) là 4 byte.

Mặt khác, các mảng ngắn mất 2 byte cho mỗi phần tử (ngoài không gian phía trước cho mảng kế toán + đối tượng).

Mảng

Các new-array opcode gọi dvmAllocArrayByClass (dòng 71) để phân bổ không gian. Điều này sau đó gọi dvmAllocPrimitiveArray (dòng 113).Trong công tắc ở dvmAllocPrimitiveArray, trường hợp 'S' được sử dụng cho một mảng ngắn. Bạn có thể thấy nó gọi allocArray (dòng 38) với chiều rộng = 2.

Trong allocArray, nó tính toán sau đây để tính toán kích thước kích thước của mảng:

size_t elementShift = sizeof(size_t) * CHAR_BIT - 1 - CLZ(elemWidth); 
size_t elementSize = length << elementShift; 
size_t headerSize = OFFSETOF_MEMBER(ArrayObject, contents); 
size_t totalSize = elementSize + headerSize; 

Đối với một đoạn ngắn, trên một hệ 32 bit, tính toán này sẽ là:

size_t elementShift = (4 * 8) - 1 - 30; //== 1; 
size_t elementSize = length << 1; //i.e. length * 2 
size_t headerSize = <some constant value>; 
size_t totalSize = length*2 + <some constant value>; 

Các mảng ngắn mất 2 byte cho mỗi phần tử.

Fields

Các new-instance opcode gọi dvmAllocObject (dòng 181) để phân bổ không gian cho các đối tượng mới. Kích thước được phân bổ dựa trên trường objectSize của ClassObject. objectSize được đặt trong computeFieldOffsets (dòng 3543). Nếu bạn tìm thấy tất cả các trường hợp fieldOffset được tăng lên trong hàm này, bạn sẽ thấy nó luôn được tăng lên theo các bước 4 byte.

Trường ngắn mất 4 byte.

+0

Đây chính xác là loại câu trả lời phân tích mà tôi đang tìm kiếm. Cảm ơn bạn! –

2

(Sẽ Đó là một bình luận, nhưng nó quá dài cho điều đó.)

Nó khá thường xuyên cho các trường 4 byte được sử dụng cho các vars cục bộ "ngắn", vì JVM là khái niệm một máy có đăng ký 4 byte, và với tất cả rác khác trong một khung ngăn xếp nó không tạo ra nhiều khác biệt.

Đối với các trường mẫu, có thể phụ thuộc vào sự cân bằng giữa lưu trữ và phải chi tiêu chu kỳ mở rộng và căn chỉnh - mở rộng thường tốn một chu kỳ nhỏ và thậm chí trên các kiến ​​trúc được cho là "bất khả tri". thường có một hình phạt cho việc truy cập off-ranh giới, vì vậy "đóng gói" các lĩnh vực mà không cần sắp xếp lại chúng để duy trì từ/doubleword ranh giới có thể chi phí hiệu suất.

Vì vậy, nếu JVM chọn "đóng gói" thì cần sắp xếp lại các trường. Các JVM Naive sẽ tránh sắp xếp lại vì điều này làm cho một số khía cạnh của JVM đơn giản hơn, nhưng (như một ví dụ) trên AS/400, chúng tôi thấy rằng các trường hợp sắp xếp lại và đóng gói tích cực tăng lên theo thứ tự cải thiện hiệu suất 30% cho các ứng dụng lưu trữ đói.

Tôi chưa bao giờ xem nội dung của Dalvik. Các JVM có nguồn gốc Mặt trời tiêu chuẩn có lịch sử (không xem xét bất kỳ điều gì gần đây) phụ thuộc vào cách bố trí/thứ tự của các thứ trong tệp .class, và do đó không phải là "tự nhiên" có khả năng sắp xếp lại. Nhưng Dalvik lại cấu thành tập tin .class và như vậy là ở một vị trí tốt hơn để làm trường instance sắp xếp lại. Lưu ý rằng để kiểm tra giả thuyết rằng Dalvik gói short trường, bạn phải tạo một lớp với vài chục trường thể hiện back-to-back, và sau đó xác định kích thước đối tượng kết quả là gì. Ngoài ra (giả sử đóng gói được nhìn thấy trong trường hợp đầu tiên), tạo ra một lớp học với các trường shortint (hoặc có thể long) xen kẽ, để xem liệu Dalvik có sắp xếp lại chúng để đạt được đóng gói hay không.

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