我有一个应用程序,读取一个CSV文件与成堆的数据行。我根据数据类型向用户提供了行数的摘要,但我想确保不会读入太多行数据而导致OutOfMemoryErrors。每一行转换成一个对象。有没有一种简单的方法以编程方式找出该对象的大小?是否有一个引用定义了一个VM的基本类型和对象引用有多大?
现在,我有代码说读取多达32,000行,但我还希望有代码说读取尽可能多的行,直到我使用了32MB的内存。也许这是另一个问题,但我还是想知道。
我有一个应用程序,读取一个CSV文件与成堆的数据行。我根据数据类型向用户提供了行数的摘要,但我想确保不会读入太多行数据而导致OutOfMemoryErrors。每一行转换成一个对象。有没有一种简单的方法以编程方式找出该对象的大小?是否有一个引用定义了一个VM的基本类型和对象引用有多大?
现在,我有代码说读取多达32,000行,但我还希望有代码说读取尽可能多的行,直到我使用了32MB的内存。也许这是另一个问题,但我还是想知道。
当前回答
如果你只是想知道在你的JVM中有多少内存被使用,有多少是空闲的,你可以尝试这样做:
// Get current size of heap in bytes
long heapSize = Runtime.getRuntime().totalMemory();
// Get maximum size of heap in bytes. The heap cannot grow beyond this size.
// Any attempt will result in an OutOfMemoryException.
long heapMaxSize = Runtime.getRuntime().maxMemory();
// Get amount of free memory within the heap in bytes. This size will increase
// after garbage collection and decrease as new objects are created.
long heapFreeSize = Runtime.getRuntime().freeMemory();
edit:我认为这可能会有帮助,因为问题作者还表示,他希望有处理“读取尽可能多的行,直到我使用了32MB内存”的逻辑。
其他回答
如果你只是想知道在你的JVM中有多少内存被使用,有多少是空闲的,你可以尝试这样做:
// Get current size of heap in bytes
long heapSize = Runtime.getRuntime().totalMemory();
// Get maximum size of heap in bytes. The heap cannot grow beyond this size.
// Any attempt will result in an OutOfMemoryException.
long heapMaxSize = Runtime.getRuntime().maxMemory();
// Get amount of free memory within the heap in bytes. This size will increase
// after garbage collection and decrease as new objects are created.
long heapFreeSize = Runtime.getRuntime().freeMemory();
edit:我认为这可能会有帮助,因为问题作者还表示,他希望有处理“读取尽可能多的行,直到我使用了32MB内存”的逻辑。
当使用JetBrains IntelliJ时,首先在|文件设置|构建,执行,部署|调试器中启用“附加内存代理”。
调试时,右键单击感兴趣的变量,选择“计算保留大小”:
假设我声明了一个名为Complex的类:
public class Complex {
private final long real;
private final long imaginary;
// omitted
}
为了查看这个类的活动实例被分配了多少内存:
$ jmap -histo:live <pid> | grep Complex
num #instances #bytes class name (module)
-------------------------------------------------------
327: 1 32 Complex
我怀疑您是否希望以编程方式完成它,除非您只是想执行一次并将其存储起来以供将来使用。这是一件代价高昂的事情。在Java中没有sizeof()操作符,即使有,它也只会计算引用其他对象的代价和原语的大小。
你可以这样做的一种方法是将它序列化到File中,然后查看文件的大小,就像这样:
Serializable myObject;
ObjectOutputStream oos = new ObjectOutputStream (new FileOutputStream ("obj.ser"));
oos.write (myObject);
oos.close ();
当然,这假设每个对象都是不同的,并且不包含对其他任何对象的非瞬时引用。
另一种策略是获取每个对象并通过反射检查其成员,并将大小相加(boolean & byte = 1字节,short & char = 2字节,等等),沿着成员层次结构向下工作。但这既乏味又昂贵,而且最终与序列化策略所做的事情相同。
对于JSONObject,下面的代码可以帮助您。
`JSONObject.toString().getBytes("UTF-8").length`
返回以字节为单位的大小
我通过将JSONArray对象写入文件来检查它。它给出了对象的大小。