Tôi muốn biết bất kỳ cách đơn giản nào để truy xuất kích thước của một đối tượng java? Ngoài ra, anyway để có được kích thước của một lớp như nhà điều hành sizeof trong c + +?Có cách nào đơn giản để có được kích thước của một đối tượng java không?
Trả lời
Có một opensource java.SizeOf project xác định kích thước của bất kỳ đối tượng Java nào của bạn trong bộ nhớ.
Giao diện Instrumentation có phương thức getObjectSize().
Tuy nhiên, điều này chỉ cung cấp cho bạn kích thước của đối tượng, không phải là các thành phần con của nó. Vì vậy, ví dụ, nó sẽ cho bạn biết rằng tất cả các đối tượng String
có cùng kích thước.
Một vấn đề khác là kích thước của một đối tượng thực sự có thể thay đổi một cách tự phát. Ví dụ, nếu bạn nhận được mã băm nhận dạng của một đối tượng và nó tồn tại một chu trình GC, thì kích thước của nó sẽ được tăng lên (ít nhất) 4 byte để lưu trữ giá trị hashcode danh tính.
Vấn đề tìm kích thước của "đối tượng" là không thể biết được ranh giới trừu tượng của đối tượng tùy ý. Có vấn đề cho một cái gì đó thậm chí đơn giản như lớp String. (Xem xét đối tượng String tạo sử dụng substring(...)
trong Java 6. Bạn có thể đối tượng char[] value
như một phần của this
, hoặc một phần của chuỗi ban đầu, hay cả hai? Điều này có nghĩa gì đối với các kích thước của các đối tượng tương ứng?)
Vì vậy, nó là không thể tránh khỏi rằng một cái gì đó như net.sourceforge.sizeof
không thể cung cấp cho một kế toán hoàn toàn chính xác của việc sử dụng không gian.
Trong khi chương trình của bạn đang chạy, có một cửa sổ terminal và chạy:
jmap -histo <process id of the java instance you want to debug>
Trong đầu ra nó mang lại số lượng và tổng kích thước của trường hợp đối tượng bằng lớp. Ví dụ: 3 72 java.util.Date
có nghĩa là có 3 đối tượng Ngày trong bộ nhớ lấy 24 byte mỗi bộ nhớ. Bạn có thể cần phải đầu ra đường ống vào một tập tin hoặc một cái gì đó nếu phần liên quan cuộn đi quá nhanh.
Hoặc, cho (nhiều) cụ thể hơn, chạy:
jmap -dump:format=b,file=heap.bin <processid>
jhat heap.bin
Sau đó mở http://localhost:7000. Bạn có thể duyệt qua các đối tượng trên heap trong trình duyệt của bạn. Thông tin
thêm:
http://docs.oracle.com/javase/6/docs/technotes/tools/share/jmap.html
http://docs.oracle.com/javase/6/docs/technotes/tools/share/jhat.html
Tôi nghĩ rằng nó luôn luôn được làm tròn lên đến 8 bằng cách này, trên Sun/Oracle JVM, ngay cả khi đối tượng là 12 byte, nó sẽ mất 16 trong bộ nhớ.
Sử dụng lớp Unsafe
từ sun.misc
bạn có thể nhận được trường bù trừ. Vì vậy, xem xét các đối tượng heap liên kết theo kiến trúc bộ xử lý và tính toán bù trừ trường tối đa, bạn có thể đo kích thước của một đối tượng Java. Trong ví dụ bên dưới, tôi sử dụng lớp phụ trợ UtilUnsafe
để tham chiếu đến đối tượng sun.misc.Unsafe
.
private static final int NR_BITS = Integer.valueOf(System.getProperty("sun.arch.data.model"));
private static final int BYTE = 8;
private static final int WORD = NR_BITS/BYTE;
private static final int MIN_SIZE = 16;
public static int sizeOf(Class src){
//
// Get the instance fields of src class
//
List<Field> instanceFields = new LinkedList<Field>();
do{
if(src == Object.class) return MIN_SIZE;
for (Field f : src.getDeclaredFields()) {
if((f.getModifiers() & Modifier.STATIC) == 0){
instanceFields.add(f);
}
}
src = src.getSuperclass();
}while(instanceFields.isEmpty());
//
// Get the field with the maximum offset
//
long maxOffset = 0;
for (Field f : instanceFields) {
long offset = UtilUnsafe.UNSAFE.objectFieldOffset(f);
if(offset > maxOffset) maxOffset = offset;
}
return (((int)maxOffset/WORD) + 1)*WORD;
}
class UtilUnsafe {
public static final sun.misc.Unsafe UNSAFE;
static {
Object theUnsafe = null;
Exception exception = null;
try {
Class<?> uc = Class.forName("sun.misc.Unsafe");
Field f = uc.getDeclaredField("theUnsafe");
f.setAccessible(true);
theUnsafe = f.get(uc);
} catch (Exception e) { exception = e; }
UNSAFE = (sun.misc.Unsafe) theUnsafe;
if (UNSAFE == null) throw new Error("Could not obtain access to sun.misc.Unsafe", exception);
}
private UtilUnsafe() { }
}
Chắc chắn có thể nhận được kích thước đối tượng, vì đối tượng của một lớp nhất định chỉ là khối bộ nhớ có kích thước cố định. Tôi đã viết đoạn mã sau để tính toán kích thước của một đối tượng. Nó cũng cung cấp một phương thức như 'sizeof' trong C++. Nó đã sẵn sàng để chạy và không phụ thuộc vào gì cả. Bạn có thể sao chép và dùng thử!
public class ObjectSizer {
public static final Unsafe us = getUnsafe();
public static boolean useCompressedOops = true;
public static int retainedSize(Object obj) {
return retainedSize(obj, new HashMap<Object, Object>());
}
private static int retainedSize(Object obj, HashMap<Object, Object> calculated) {
try {
if (obj == null)
throw new NullPointerException();
calculated.put(obj, obj);
Class<?> cls = obj.getClass();
if (cls.isArray()) {
int arraysize = us.arrayBaseOffset(cls) + us.arrayIndexScale(cls) * Array.getLength(obj);
if (!cls.getComponentType().isPrimitive()) {
Object[] arr = (Object[]) obj;
for (Object comp : arr) {
if (comp != null && !isCalculated(calculated, comp))
arraysize += retainedSize(comp, calculated);
}
}
return arraysize;
} else {
int objectsize = sizeof(cls);
for (Field f : getAllNonStaticFields(obj.getClass())) {
Class<?> fcls = f.getType();
if (fcls.isPrimitive())
continue;
f.setAccessible(true);
Object ref = f.get(obj);
if (ref != null && !isCalculated(calculated, ref)) {
int referentSize = retainedSize(ref, calculated);
objectsize += referentSize;
}
}
return objectsize;
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static int sizeof(Class<?> cls) {
if (cls == null)
throw new NullPointerException();
if (cls.isArray())
throw new IllegalArgumentException();
if (cls.isPrimitive())
return primsize(cls);
int lastOffset = Integer.MIN_VALUE;
Class<?> lastClass = null;
for (Field f : getAllNonStaticFields(cls)) {
if (Modifier.isStatic(f.getModifiers()))
continue;
int offset = (int) us.objectFieldOffset(f);
if (offset > lastOffset) {
lastOffset = offset;
lastClass = f.getClass();
}
}
if (lastOffset > 0)
return modulo8(lastOffset + primsize(lastClass));
else
return 16;
}
private static Field[] getAllNonStaticFields(Class<?> cls) {
if (cls == null)
throw new NullPointerException();
List<Field> fieldList = new ArrayList<Field>();
while (cls != Object.class) {
for (Field f : cls.getDeclaredFields()) {
if (!Modifier.isStatic(f.getModifiers()))
fieldList.add(f);
}
cls = cls.getSuperclass();
}
Field[] fs = new Field[fieldList.size()];
fieldList.toArray(fs);
return fs;
}
private static boolean isCalculated(HashMap<Object, Object> calculated, Object test) {
Object that = calculated.get(test);
return that != null && that == test;
}
private static int primsize(Class<?> cls) {
if (cls == byte.class)
return 1;
if (cls == boolean.class)
return 1;
if (cls == char.class)
return 2;
if (cls == short.class)
return 2;
if (cls == int.class)
return 4;
if (cls == float.class)
return 4;
if (cls == long.class)
return 8;
if (cls == double.class)
return 8;
else
return useCompressedOops ? 4 : 8;
}
private static int modulo8(int value) {
return (value & 0x7) > 0 ? (value & ~0x7) + 8 : value;
}
private static Unsafe getUnsafe() {
try {
Field f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
return (Unsafe) f.get(Unsafe.class);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) {
System.out.println(retainedSize("Hello Leeeeeeeen"));
}
}
- 1. Có cách nào để chuyển đổi đối tượng Ember thành đối tượng javascript đơn giản không?
- 2. Có cách nào đơn giản để lấy kích thước hình ảnh trong Ruby không?
- 3. Làm thế nào tôi có thể nhận được kích thước của một đối tượng trong HttpRuntime.Cache?
- 4. Đối tượng đơn giản của Python đơn giản
- 5. Tính kích thước byte của đối tượng Java
- 6. Có cách nào đơn giản để xác định kích thước loại trong C#?
- 7. Java Reflection - Lấy kích thước của đối tượng mảng
- 8. Java - cách tốt nhất để triển khai mảng đối tượng có kích thước động
- 9. Đối tượng Ruby có giới hạn kích thước không?
- 10. Android & Dalvik - Nhận kích thước của một đối tượng
- 11. Đo kích thước của đối tượng HttpSession
- 12. Thay đổi kích thước đơn giản của UIImage trong XCODE
- 13. Vals cuối cùng có tăng kích thước đối tượng không?
- 14. Lỗi biên dịch C: "Đối tượng có kích thước biến có thể không được khởi tạo"
- 15. python. lấy kích thước của một đối tượng
- 16. Kích thước của một đối tượng trong thời gian chạy
- 17. Cách viết một đối tượng đơn giản trong PHP
- 18. Java: Cách đơn giản nhất để có được từ cuối cùng trong một chuỗi
- 19. Kích thước tối đa của đối tượng có thể được lưu trong memcached với memcache.py
- 20. Nhận dạng đối tượng đơn giản
- 21. Có thư viện Java FTP Server đơn giản nào có thể nhúng được không?
- 22. Kích thước đối tượng .NET
- 23. Tìm hiểu kích thước của một đối tượng đa hình
- 24. Có cách nào để tạo một đối tượng python sẽ không thể sắp xếp được không?
- 25. Bất kỳ cách đơn giản nào để có được độ dài hàng đợi của ActiveMQ?
- 26. Cách đo kích thước của đối tượng Ruby?
- 27. Có cách nào đơn giản để thực hiện một Combobox được kiểm tra trong WinForms
- 28. Cách đơn giản để có được loại lớp bao bọc trong Java
- 29. Có thư viện đơn giản nào sẽ hiển thị đối tượng JSON dưới dạng cây không?
- 30. Chia đối tượng NSData thành các đối tượng NSData khác có kích thước nhất định
http://stackoverflow.com/questions/52353/in-java-what-is-the-best-way-to-determine-the-size-of-an-object – NAVEED
bạn có thể có nhiều riêng. Bạn đang nói về kích thước trong bộ nhớ mà một đối tượng java đang sử dụng? –
Xem http://stackoverflow.com/questions/757300/programatically-calculate-memory-occupied-by-a-java-object-including-objects-it – user371320