[英]How to get amount of serialized bytes representing a Java object?
我將使用什么語法來獲取表示字符串的字節數,並將它們與表示保存該字符串的ArrayList
的字節數進行比較,例如?
我正在使用多代理代理系統通過消息發送對象,我想跟蹤每條消息占用多少空間。 只要該方法與對象的實際大小成比例地縮放,該方法就不必是准確的。 例如,長度為4的字符串向量將報告為小於長度為5的字符串向量。
您可以使用ObjectOutputStream
和ByteArrayOutputStream
將對象轉換為字節數組:
public static int sizeof(Object obj) throws IOException {
ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteOutputStream);
objectOutputStream.writeObject(obj);
objectOutputStream.flush();
objectOutputStream.close();
return byteOutputStream.toByteArray().length;
}
我剛測試了這個。 你想要計算的大小的對象需要實現Serializable
(這意味着你可能必須將每個對象標記為僅僅為了獲得它的大小。可能不可取)。 我寫了一個快速而又臟的程序來測試它:
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class Sizeof {
public static class Person implements Serializable {
private String name;
private String age;
public Person(String name, String age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
public static void main(String[] args) {
Person p1 = new Person("Alby", "20");
Person p2 = new Person("VeryLongName", "100");
String s1 = "This is it";
String s2 = "This";
try {
System.out.println("p1 " + sizeof(p1));
System.out.println("p2 " + sizeof(p2));
System.out.println("s1 " + sizeof(s1));
System.out.println("s2 " + sizeof(s2));
}
catch(Exception e) {
e.printStackTrace();
}
}
public static int sizeof(Object obj) throws IOException {
ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteOutputStream);
objectOutputStream.writeObject(obj);
objectOutputStream.flush();
objectOutputStream.close();
return byteOutputStream.toByteArray().length;
}
}
哪個給了我:
p1 85
p2 94
s1 17
s2 11
編輯
Stephen C的回答強調了這種方法的一些注意事項。
在調查超出memcache大小的服務器錯誤時,我需要准確地檢查每個memcache。 為了避免大對象的大字節數組的開銷,我將OutputStream擴展為計數器:
public class CheckSerializedSize extends OutputStream {
/** Serialize obj and count the bytes */
public static long getSerializedSize(Serializable obj) {
try {
CheckSerializedSize counter = new CheckSerializedSize();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(counter);
objectOutputStream.writeObject(obj);
objectOutputStream.close();
return counter.getNBytes();
} catch (Exception e) {
// Serialization failed
return -1;
}
}
private long nBytes = 0;
private CheckSerializedSize() {}
@Override
public void write(int b) throws IOException {
++nBytes;
}
@Override
public void write(byte[] b, int off, int len) throws IOException {
nBytes += len;
}
public long getNBytes() {
return nBytes;
}
}
您可以將每個對象序列化為數組並比較每個數組的長度。 在一般情況下,這不是非常准確,但通常給出了很好的近似值。
查看ObjectOutputStream(可用於序列化對象並將其轉換為Bytes)和ByteArrayOutputStream(可用於保存序列化字節)。
我認為你沒有太多選擇,只能修改你的代碼,以便它在運行時測量消息大小。
您可以序列化示例對象並捕獲和測量序列化大小。 這有以下問題:
如果您可以對此進行管理,那么如果您可以測量實際消息,您將獲得更准確的結果。 這很可能需要修改代理框架以計算,測量和(理想地)將消息分類為不同類型 。 框架可能已經有了鈎子來做這件事。
只要該方法與對象的實際大小成比例地縮放,該方法就不必是准確的。 例如,長度為4的字符串向量將報告為長度為5的字符串向量。
(我認為你的意思是小於 ...)
您的示例說明了嘗試估計序列化對象大小的問題之一。 大小為4的Vector<String>
的序列化可能更小......或者更大......一個大小為5的Vector<String>
。它取決於String值是什么。 此外,如果消息包含兩個Vector<String>
對象,則向量占用的序列化大小將小於單獨序列化時兩個向量的大小總和。
看看: http : //www.javaworld.com/javaworld/javaqa/2003-12/02-qa-1226-sizeof.html
我想到的最接近的事情就是將它序列化並讀取字節數
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.