繁体   English   中英

java内存中大小优化

[英]java in-memory size optimization

我正在编写一些需要在内存中保存大量数据的“大数据”软件。 我用c ++写了一个非常好的原型。 然而,实际的最终用户通常使用Java编写代码,因此他们要求我也编写Java原型。

我已经完成了java中内存占用的背景阅读和一些初步测试。 例如,假设我有这个对象

public class DataPoint{

    int cents, time, product_id, store_id;

    public DataPoint(int cents, int time, int product_id, int store_id){
    this.cents = cents;
    this.time = time;
    this.product_id = product_id;
    this.store_id = store_id;
    }
}

在C ++中,这个结构的大小是16个字节,这是有道理的。 在Java中,我们必须是间接的。 如果我创建了例如10m的这些对象并使用Runtime.totalMemory() - Runtime.freeMemory()之前和之后然后根据需要进行除法,每个结构大约需要36个字节。 一个~2.4倍的内存差异非常讨厌; 当我们试图在内存中保存数亿个DataPoints时,它会变得丑陋。

我在某处看到,在Java中这样的情况下,将数据存储为数组更好 - 实质上是基于列的存储而不是基于行的存储。 我想我理解这一点:基于列的方式减少了引用数量,也许JVM甚至可以智能地将整数打包成8字节的字。

我可以使用哪些其他技巧来减少内存占用的内存占用内存块,该内存块具有一个非常大的维度(数百万/数十亿的数据点)和一个非常小的维度(O(1)列数/变量)?

结果是将数据存储为4个int数组,每个条目恰好使用16个字节。 经验教训:小对象在java中具有令人讨厌的比例开销。

查看数据结构在Java中占用多少内存并不是那么简单。 totalMemory()显示为vm分配的空间,该空间大于实际使用情况。 您可以尝试使用显示数据结构空间消耗的Java分析器,它们很容易设置和运行。 一个方便的免费工具是Java自己的VisualVM ,例如显示应用程序的内存行为,如果使用它,您还将学习Java的GC如何工作。

显示性能足迹的VisualVM屏幕截图(来自http://visualvm.java.net/features.html的图片): 在此输入图像描述

如果可能的话,你还应该考虑让变量最终。 它允许Java VM更好地优化代码位(不确定它是否可以节省空间)。

首先, Java的对象总是比C++版本略大,因为该对象封装了运行时类型信息,使您能够执行C++无法实现的instanceof等。 此外,它还有助于您自己手动执行内存管理,因此您也可以将C++代码的这一部分视为代码库的一部分。

您可以查看Flyweight模式以减少内存需求,以便重用DataPoints (使类为Immutable )。 我假设如果你有数十亿的点,你说有些可能是相同的值。
我相信这里的其他人会提供一些关于内存空间优化的具体信息

根据值范围,您可以使用较小的数据类型。 对于某些成员,你可以使用byte或short吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM