我正在为我的大学重构一小部分开源大型配置管理系统。
我们正在使用一些像Weka这样的机器学习的开源工具,而我分配给重构的方面是处理数据挖掘和构建规则。
我们在利物浦和日本使用的开源文件运行良好,但在大型项目中使用该程序时存在一些内存使用问题。
我已经隔离了主要的内存占用,并得出结论我需要找出一个不同的数据结构来存储和操作数据。就目前而言,该程序正在使用最终成为非常大的整数,对象,字符串等多维数组。
在我们导出行为规则之后,有几种方法可以简单地重新配置关联的设置。在许多情况下,我们只是添加或减去单个元素,或简单地展平多维数组。
我主要使用C / C ++进行编程,因此我不是Java中可用数据结构的专家。我想要替换静态数组是一个动态结构,可以轻松调整大小,而无需创建第二个多维数组。
现在发生的事情是,每次我们添加和删除多维数组中的规则,对象或其他杂项数据时,我们都必须创建一个全新的结构。然后我们立即复制到新阵列。
我希望能够简单地使用相同的多维数组,只需添加一个新的行和列。随后,我希望能够通过简单地保存临时值并覆盖以前的值,左移,右移等来操纵结构中的数据。
任何人都可以想到Java中适合该法案的任何数据结构吗?
在相关的说明中,我已经研究过显式垃圾收集,但是我发现我只能通过调用System.Gc()或通过调整来操纵JVM的垃圾收集行为来真正建议收集JVM。有更好或更有效的方法吗?
此致 EDM
答案 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中明确处理。通常,您希望在首次出现内存时查找内存泄漏。当发生这种情况时,查找不应该死的后台线程或缓存中的强引用。如果您想阅读有关后一问题的一些内容,可以启动here和here。