动态多维Java结构替换静态多维数组

时间:2013-06-26 04:24:56

标签: java memory-management data-structures

我正在为我的大学重构一小部分开源大型配置管理系统。

我们正在使用一些像Weka这样的机器学习的开源工具,而我分配给重构的方面是处理数据挖掘和构建规则。

我们在利物浦和日本使用的开源文件运行良好,但在大型项目中使用该程序时存在一些内存使用问题。

我已经隔离了主要的内存占用,并得出结论我需要找出一个不同的数据结构来存储和操作数据。就目前而言,该程序正在使用最终成为非常大的整数,对象,字符串等多维数组。

在我们导出行为规则之后,有几种方法可以简单地重新配置关联的设置。在许多情况下,我们只是添加或减去单个元素,或简单地展平多维数组。

我主要使用C / C ++进行编程,因此我不是Java中可用数据结构的专家。我想要替换静态数组是一个动态结构,可以轻松调整大小,而无需创建第二个多维数组。

现在发生的事情是,每次我们添加和删除多维数组中的规则,对象或其他杂项数据时,我们都必须创建一个全新的结构。然后我们立即复制到新阵列。

我希望能够简单地使用相同的多维数组,只需添加一个新的行和列。随后,我希望能够通过简单地保存临时值并覆盖以前的值,左移,右移等来操纵结构中的数据。

任何人都可以想到Java中适合该法案的任何数据结构吗?

在相关的说明中,我已经研究过显式垃圾收集,但是我发现我只能通过调用System.Gc()或通过调整来操纵JVM的垃圾收集行为来真正建议收集JVM。有更好或更有效的方法吗?

此致  EDM

5 个答案:

答案 0 :(得分:1)

如果矩阵中有很多nulls / zero / falses / empty-strings,那么可以使用sparse matrix实现来节省空间。 Matrix-toolkits有几个稀疏矩阵,您可以使用/修改以满足您的需要,或者您可以使用带有{x,y}元组的散列图作为键。 (hashmap还有一个优点,即有几个外部hashmap实现可用,例如BerkeleyDB,因此你不太可能会耗尽内存。)

答案 1 :(得分:1)

要使用动态结构替换静态数组,请使用随数据自动增长的ArrayList。要使用二维数据结构,请使用List List作为

List<List<Integer>> dataStore = new ArrayList<List<Integer>>();
dataStore.add(new ArrayList<Integer>());
dataStore.add(Arrays.asList(1, 2, 3, 4));

// Access [1][3] as
System.out.println(dataStore.get(1).get(3)); // prints 4

因为,你谈到控制垃圾收集(Java实际上它自己做得很好)似乎内存管理是至关重要的,因为这是导致重新首先考虑因素。

您可以查看专注于共享对象的Flyweight GoF模式,而不是重复它们以减少应用程序的内存占用。要启用共享flyweight对象,需要 immutable

Psuedo代码:

// adding a new flyweight obj at [2][1]
fwObjStore.get(2).set(1, FWObjFactory.getInstance(fwKey));

public class FWObjFactory {
    private static Map<String, FWObject> fwMap = new HashMap<String, FWObject>();

    public static getInstance(String fwKey) {
        if (!fwMap.containsKey(fwKey)) {
            fwMap.put(fwKey, newFwFromKey(fwKey));
        }
        return fwMap.get(fwKey);
    }

    private static FWObject newFwFromKey(String fwKey) {
        // ...
    }
}

答案 2 :(得分:0)

Java中没有多维事物.Java有数组数组。

您可以将ArrayList与type参数一起用作ArrayList

ArrayList<ArrayList<yourType>> myList = new ArrayList<ArrayList<yourType>>();

另外,不要担心GC ..它会在需要时收集..

答案 3 :(得分:0)

我会考虑使用“列表清单”。例如,您可以声明类似

的内容
List<List<Object>> mArray = new ArrayList<List<Object>>();

每当您需要添加新的“行”时,您可以执行以下操作:

mArray.add (new ArrayList<Object>());

查看List界面,看看你可以用Java中的List做什么,以及哪些类实现了界面(或者自己动手!)。

答案 4 :(得分:0)

为什么不将两个Lists纠缠在一起?像这样:

List<List<String>> rowColumns = new ArrayList<>();

// Add a row with two entries, or columns:
List<String> oneRow = Arrays.asList("Hello", "World!");
rowColumns.add(oneRow);

另外,请考虑使用Map将条目映射到列表。

垃圾收集通常不必在Java中明确处理。通常,您希望在首次出现内存时查找内存泄漏。当发生这种情况时,查找不应该死的后台线程或缓存中的强引用。如果您想阅读有关后一问题的一些内容,可以启动herehere