java - 如何在内存方面为四叉树叶的 "organize"数据结构?

标签 java mobile out-of-memory coordinates quadtree

我有 .hgt 文件,其中包含 (1201x1201) 个 16 位整数。我将此文件存储在最高级别为 5 的四叉树中。在级别 5 的叶子中,我有点数组列表:

public class Point {
    short x,y,v;
}

x,y - 坐标, v - 海拔。

一切正常,但它需要太多内存,因为我正在创建 1201x1201= cca 1.44M 的对象。我在移动应用程序 (Android) 上工作,所以这是个问题,因为插入所有点需要超过 20 秒,它会“吃掉”所有内存。有什么办法可以减少这种情况吗?

堆大小:49.258 MB

已分配:44.733 MB

数据对象:(计数:1 477 454),(总大小:34.081 MB)

hgt file format

最佳答案

我不是 JVM 专家,但上次我检查了一个 Java 对象有 8 字节(64 位)的元数据,它似乎同样需要 64 位对齐。这在 32 位 Android 设备上可能有所不同,但根据我的发现,您的 Point 对象需要 16 个字节而不是 6 个字节,如下所示:

public class Point {
    // 8 byte metadata

    // 6 bytes of data.
    short x,y,v;

    // 2 bytes of padding for alignment of metadata.
}

...类似的东西。因此,这比 3 个 16 位 shorts 最佳所需的内存使用量多 2.67 倍。因此,将点的内存减少到一半以下并改善引用局部性的一种解决方案是将所有内容存储在一个或多个巨大的 short 数组中,例如:

short xyz[num_points * 3];

这将需要非常、非常、非常接近最佳内存量(只需一点点开销,在这种情况下绝对微不足道,以存储数组的一些元数据,例如其长度)。

也就是说,假设 Point 是 16 字节,这只能解释大约一半的爆炸性内存使用(点约 23 兆字节)。另一个很可能是您的四叉树节点本身。不过,如果使用上述技术,您可以将其从 23 兆字节减少到 ~8.6 兆字节。

对于剩余的内存使用,我的第一个建议是避免为每个叶节点存储一个单独的 ArrayList。例如,您可以只存储一个大数组列表中第一个点的索引(整棵树只存储一个),并且可能还有一个整数表示该叶子中存储的元素数。这是一个 C-ish 伪代码示例,但您应该能够使您的四叉树节点至少像这样:

struct QuadTreeNode
{
     // Stores AABB.
     float x1, x2, y1, y2;

     // Stores first child or -1 if empty.     
     int first_child;

     // Stores first element or -1 if this is not a leaf.
     int first_element;
};

struct QuadTree
{
     // Stores all the nodes in the quad tree. The 4
     // children of a node are stored contiguously.
     QuadTreeNode nodes[];

     // Stores all the elements in the quad tree. The
     // elements at the leaves are stored contiguously.
     Element elements[];
};

这甚至不是很紧凑,但它相当紧凑。

关于java - 如何在内存方面为四叉树叶的 "organize"数据结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28732780/

相关文章:

java - 带有 Logback 的 Spring Boot 应用程序不会作为 Systemd 服务登录到指定位置

java - 与代理的 HTTPS 连接导致 SSLHandshakeException

ios - 如何使我的字体大小在各种设备上看起来不错? UIWebView 中 iPad 和 iPhone 的不同视口(viewport)

ios - lsof 在 iOS 中给出 "information error: Cannot allocate memory"

java - 运行多线程代码时内存不足异常

java - 在文本javafx中显示变量值

java - 使用 getResourceAsStream 与 InputStreamReader 发生 NullPointerException

php - 添加 URL 参数以使用 Zend Framework 切换 View 的最佳方法是什么?

java - 移动java应用程序

java - 使用 Hibernate 时内存使用率高