[英]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.