2012-11-30 27 views
9

Theo this question, cách tiêu chuẩn để xác định kích thước bộ nhớ của một đối tượng trong Java là bằng cách sử dụng java.lang.instrumentation. Sau một số nghiên cứu, có vẻ như không có cách cụ thể nào để đạt được điều này, vì vậy phương pháp Java cũng nên áp dụng ở đây.xác định kích thước của đối tượng: cách tốt nhất để sử dụng thiết bị đo đạc trong scala/sbt

Thật không may, đối với một lập trình viên Scala không có nền Java, nó không hoàn toàn đơn giản để thích ứng với kỹ thuật này trong Scala. Câu hỏi của tôi là:

Câu hỏi 1

gì chính xác đang xảy ra ở đây? Tôi đoán lý do tại sao chúng tôi phải đặt một lớp như ObjectSizeFetcher trong một JAR riêng biệt là để đảm bảo rằng nó được tải bằng cách nào đó trước khi chương trình thực tế mà chúng tôi muốn sử dụng nó. Tôi cho rằng không thể sử dụng thiết bị mà không có mục nhập Premain-Class và thông số -javaagent:TheJarContainingObjectFetcher.jar?

Câu hỏi 2

Có một cách đơn giản để thực hiện khối lượng công việc hoàn thành trong SBT? Hiện tại tôi chỉ thấy một giải pháp hơi cồng kềnh: đầu tiên tôi phải thiết lập một dự án SBT thứ cấp nơi tôi xác định ObjectSizeFetcher và gói nó vào một JAR. Cho đến nay tôi đã không tìm ra cách tự động thêm mục nhập Premain-Class vào JAR trong quá trình đóng gói, vì vậy tôi sẽ phải giải quyết thủ công. Hơn tôi có thể thêm JAR kết quả cho các thư viện địa phương của dự án mà tôi muốn sử dụng getObjectSize. Đối với dự án này, tôi phải kích hoạt fork in run và sử dụng javaOptions in run += "-javaagent:TheJarContainingObjectFetcher.jar". Có một luồng công việc đơn giản hơn (và ít xâm nhập) hơn để nhanh chóng sử dụng thiết bị đo đạc trong một dự án SBT hiện có không? Có lẽ tôi có thể nói trực tiếp với SBT về một số Premain-Class để làm cho JAR phụ này không cần thiết?

Câu hỏi 3

Bạn có đề nghị một cách hoàn toàn khác nhau để đánh giá việc sử dụng bộ nhớ của một đối tượng trong Scala?

+1

Tôi ước đã có một cách gọn gàng hơn để thực hiện điều đó cho Scala trong SBT giao diện REPL .... – matanster

Trả lời

2

Trả lời 1: Có, nếu bạn muốn iinstrumentation, bạn cần phải có được một ví dụ. Bạn có lẽ không thể có được nó mà không có Premain-Class và -javaagent.

Trả lời 2: Bạn có thể (và có thể cần) sử dụng trình nạp lớp và tạo dự án khởi động rất đơn giản (bằng Java hoặc trong Scala với Proguard). Có hai lý do:

Lý do đầu tiên: conveniency. Bạn có thể sử dụng java.net.URLClassLoader để bao gồm thư viện Scala chuẩn và thư mục lớp của dự án của bạn. Bạn sẽ không cần phải đóng gói lại nó trong JAR nữa khi thử nghiệm.

Lý do thứ hai: ngăn chặn địa ngục JAR. Bạn có thể biết rằng Scala không tương thích nhị phân. Bạn cũng nên biết rằng tác nhân Java được nạp với ứng dụng trong cùng một trình nạp lớp. Nếu trình nạp lớp bao gồm thư viện Scala, ứng dụng không thể đơn giản sử dụng phiên bản Scala khác. Tuy nhiên, nếu tác nhân Java không trực tiếp sử dụng thư viện Scala (ví dụ nó là một ứng dụng bootstrap và nạp tác nhân thực và các thư viện của nó trong một trình nạp lớp khác), ứng dụng được thiết bị này có thể sử dụng bất kỳ thư viện Scala nào.

Trả lời 3: Tôi cũng có thể sử dụng thiết bị đo đạc.

2

Trả lời 3: bạn có thể có một cái nhìn để ktoso/sbt-jol mà hiển thị JOL (Java Object Layout), tức là phân tích các phương án bố trí đối tượng trong JVM

// project/plugins.sbt 
addSbtPlugin("pl.project13.sbt" % "sbt-jol" % pluginVersionHere) 

It does include the size: 

> jol:internals example.Entry 

... 
[info] example.Entry object internals: 
[info] OFFSET SIZE TYPE DESCRIPTION     VALUE 
[info]  0 12  (object header)    N/A 
[info]  12  4 int Entry.value     N/A 
[info]  16  4 String Entry.key      N/A 
[info]  20  4  (loss due to the next object alignment) 
[info] Instance size: 24 bytes 
[info] Space losses: 0 bytes internal + 4 bytes external = 4 bytes total