java - 降低Java中数据结构的内存占用

标签 java memory-management data-structures

我正在开发一种存储数据样本的内存存储解决方案。这是针对多线程趋势应用程序的,该应用程序不断将项目写入存储阵列,并定期从存储阵列中删除项目。它将存储最近24小时的样本。我需要能够完整或部分地获取数据。由于这些要求,我选择使用 CopyOnWriteArrayList。

存储解决方案存储在

CopyOnWriteArrayList<Point>.

我编写了两个类来容纳数据:Point 和 Samples。

点组成:

private int ioId;
private int machineId;
private jPointType pointType; //(int)
private String subfield;
private long startTimestamp;
private long endTimestamp;
private int pruneLock;
private jTrendReqType predefType; //(int)

CopyOnWriteArrayList<Sample> dataList;

示例包括:

Long timestamp;
double data;

我目前正在使用 2/秒数据和 30 个点(每个点 7200 个样本)进行测试。我运行了 1 小时的测试,通过任务管理器看到使用量增加了约 10MB。最终每个样本大约有 45 个字节。对于我存储的数据类型来说,这似乎相当高。 Java 开销是否太大,或者我做的事情效率低下?

最佳答案

好吧,让我们看看您的Sample 类:

Long timestamp;
double data;

来自此另一个 answerLong 大约需要 16 个字节(long 需要 8 个字节,另外还有 8 个字节的开销。

在 Java 中,double 的内存占用为 8 个字节。

Sample对象引用至少增加了8个字节(需要存储一个long来引用内存地址)。

因此,Sample 对象本身就有 32 个字节长。

但是,您计算出每个示例的平均存储大小为 45 字节。

可能还有其他原因:

  • Point 对象包含 String,大约为 8 字节 + 2 字节 * 长度
  • CopyOnWriteArrayList 实现的开销
  • 未释放的内存 - 未使用但尚未被 JVM 释放的内存。

然而,最可能的原因可能是未释放的内存。由于 Java 的运行方式,只有在运行垃圾回收 (GC) 时才会释放内存(并且没有保证强制其运行的方法)。因为您使用的是 CopyOnWriteArrayList,所以在添加对象时会不断在幕后创建新列表,而 JVM 还没有释放它们,因为 GC 尚未运行。

这是一个link有关 Java 垃圾收集机制的一些 Oracle 文档。

关于java - 降低Java中数据结构的内存占用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46350836/

相关文章:

java - 如何创建新的 "circle"datepicker android 对话框

算法分析 - 在 O(1) 中使用冲突列表进行哈希搜索

javascript - 我在将 indexOf 转换为 for 循环时遇到问题,因此我得到了错误的答案

java - 从 Spring Security 2.0.2 升级到 3.2.5.RELEASE 后出现 org.springframework.beans.factory.SmartInitializingSingleton 错误

java - 如何从 jax-rs 模拟 StreamingOutput

Java Animation,以1x,1y的频率更新动画

ios - 是否可以调试 "Terminated due to memory error"?

c++ - 指针的返回 vector ——理解

c - 当您对现有变量调用 malloc 时会发生什么?

java - 为什么要以初始容量启动 ArrayList?