在 Java 中为多个(数百万)小对象(包含 3 到 6 个双精度对象,可能是字符串)分配内存的最佳方法是什么(最少的内存消耗/交换)?
我可以想到三种不同的策略:
天真:什么都不做,让虚拟机处理内存。
工厂风格:通过工厂类创建对象。工厂一次创建多个对象(每批大约数千个)并处理对象回收(如果有使用的对象,则无需创建新对象)。
数组样式:将数据存储在基本数组中。通过索引号访问数据。
澄清: 目标平台的内存非常低(512 兆字节)。
在 Java 中为多个(数百万)小对象(包含 3 到 6 个双精度对象,可能是字符串)分配内存的最佳方法是什么(最少的内存消耗/交换)?
我可以想到三种不同的策略:
天真:什么都不做,让虚拟机处理内存。
工厂风格:通过工厂类创建对象。工厂一次创建多个对象(每批大约数千个)并处理对象回收(如果有使用的对象,则无需创建新对象)。
数组样式:将数据存储在基本数组中。通过索引号访问数据。
澄清: 目标平台的内存非常低(512 兆字节)。
选项 1。当然。几百万个对象没什么特别的,VM 可以轻松管理它。
选项 2 可能不会对内存使用产生影响,而数字 3 是可用的最差选项。请参阅 Effective Java,第 2 版中的第 55 项。
选项 3 当然是最有效的记忆。
例子:
class Point {
double x;
double y;
}
Point 对象需要 12,x 和 y 需要 2 * 8 = 28 个字节
Point[]:使用 Point 对象数组:每个点 28 个字节(数组本身需要 16 个字节)
现在为
int[] xycoords
: order: x1,y1,x2,y2,.....xn,yn:
每个 x,y 坐标需要 16 个字节。与类点相比,这是 57%
想象一下,您已经构建了导航系统,并且由于次优数据表示,您只能存储一半的欧洲。
但是
虽然选项 3 可以节省内存,但我建议对第一个版本使用 obejct 方法。数组方法有更多的编码错误概率,特别是对于复杂的算法。
一旦版本 1 工作(并且希望您有单元测试),您可以使用数组方法实现 v2。并检查您的单元测试是否仍然有效。
假设最坏的情况(6 双),一切都应该适合内存。
解释:你说双而不是双。如果我记得正确的话,包装器开销是 16 个字节。这意味着 16(包装器开销)+ 8(双精度值)= 每个 Double 24 字节。6 双倍 200 万 : ~ 274 Mo
结果:选择选项 1。
如果想要一些优化提示: