java内存大小优化

标签 java memory optimization

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

我已经完成了有关 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 倍的内存差异非常令人讨厌;当我们试图在内存中保存数亿个数据点时,它会变得很难看。

我在某处读到,在类似这种情况下,Java 最好将数据存储为数组——本质上是基于列的存储,而不是基于行的存储。我想我明白这一点:基于列的方式减少了引用的数量,也许 JVM 甚至可以智能地将 int 打包成 8 字节的字。

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

事实证明,将数据存储为 4 个 int 数组每个条目正好使用 16 个字节。教训:在 Java 中,小对象的开销成比例地令人讨厌。

最佳答案

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

显示性能足迹的 VisualVM 屏幕截图(图片来自 http://visualvm.java.net/features.html): enter image description here

如果可能,您还应该考虑将变量设为最终变量。它允许 Java VM 更好地优化代码(但不确定它是否节省空间)。

关于java内存大小优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14103882/

相关文章:

java - JSON 的 Java 正则表达式无效

java - Windows - 在哪里找到 .bashrc 文件以增加堆大小

java - OpenCV:有关 Sobel Dritevatives 的教程在 Android 上不起作用,出现 nullpointerException

excel - 使用 VBA 在 Excel 中刷新对 VBProject.VBComponents 所做的更改

optimization - 降低这个公式的复杂性?

c - Linux 上的 read() 和页对齐缓冲区

java - 如何限制 Hibernate Envers 中的审计类型

mysql - 多个 mysql 连接占用大量内存

ios - 防止在 iOS 中分配类

database - Titan 图形数据库太慢,有 100000 多个带索引的顶点如何优化它?