我有一个应用程序,读取一个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内存”的逻辑。

其他回答

可以使用java.lang.instrument包。

编译并将这个类放入JAR:

import java.lang.instrument.Instrumentation;

public class ObjectSizeFetcher {
    private static Instrumentation instrumentation;

    public static void premain(String args, Instrumentation inst) {
        instrumentation = inst;
    }

    public static long getObjectSize(Object o) {
        return instrumentation.getObjectSize(o);
    }
}

将以下内容添加到您的清单中。MF:

Premain-Class: ObjectSizeFetcher

使用getObjectSize()方法:

public class C {
    private int x;
    private int y;

    public static void main(String [] args) {
        System.out.println(ObjectSizeFetcher.getObjectSize(new C()));
    }
}

调用:

java -javaagent:ObjectSizeFetcherAgent.jar C

没有方法调用,如果这是你想要的。只要稍加研究,我想你就可以自己写了。一个特定的实例具有一个固定的大小,该大小来自引用和原语值的数量以及实例簿记数据。您可以简单地遍历对象图。行类型变化越少,越容易。

如果这太慢或者麻烦太多,总有好的老式的行计数经验法则。

对于JSONObject,下面的代码可以帮助您。

`JSONObject.toString().getBytes("UTF-8").length`

返回以字节为单位的大小

我通过将JSONArray对象写入文件来检查它。它给出了对象的大小。

假设我声明了一个名为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

一个可能的答案是2022年。

https://github.com/ehcache/sizeof

https://mvnrepository.com/artifact/org.ehcache/sizeof

https://mvnrepository.com/artifact/org.ehcache/sizeof/0.4.0

版本0.4.0只有一个(编译)依赖

https://mvnrepository.com/artifact/org.slf4j/slf4j-api

这是一件好事。

示例代码:

//import org.ehcache.sizeof.SizeOf;

SizeOf sizeOf = SizeOf.newInstance(); // (1)
long shallowSize = sizeOf.sizeOf(someObject); // (2)
long deepSize = sizeOf.deepSizeOf(someObject); // (3)