【发布时间】:2016-10-12 09:30:12
【问题描述】:
首先感谢您的帮助。 我知道 java 的引用传递机制,我需要从文本文件中读取一百万行(一个单词 + a_list_of_integers 每行)并将它们放入一些结构中,这些结构是类属性、一个 hashmap 和两个 arraylist。
问题在于,使用下面的代码,编写以节省内存,重用列表“termine_frequenza”,当我尝试从“频率”数组列表或“dictionaryMarTD”哈希图中获取和元素时,返回的列表始终是我添加的最后一个列表。 将“Arraylist termine_frequenza”的声明添加到 While 显然可以解决问题,但由于多次声明,我收到了一个可预见的“超出 GC 开销限制”错误(我试图增加堆或禁用它,但 GC 试图填充 cpu 容量释放内存。
问题很简单:如何在节省内存的同时获得正确的读数?谢谢。
//Class attributes
private HashMap<String, ArrayList> dictionaryMapTD;
private ArrayList<String> words;
private ArrayList<ArrayList> frequency;
//This is the code of a method of the class that reads from a file
br = new BufferedReader(new FileReader("dictionary.txt"));
s = br.readLine();
String[] splitted;
ArrayList<Integer> termine_frequenza = new ArrayList<>();
while(s!=null)
{
termine_frequenza.clear();
splitted = s.split(" ");
words.add(splitted[0]);
for (int i = 1; i < splitted.length; i++)
{
termine_frequenza.add(Integer.valueOf(splitted[i]));
}
frequency.add(termine_frequenza);
dictionaryMapTD.put(splitted[0], termine_frequenza);
s = br.readLine();
}
//END
【问题讨论】:
-
我知道 java 的引用传递机制:那么你应该意识到你的代码创建了一个单一的频率列表,在每次迭代时清除它,并存储许多引用到地图中的那个唯一列表。每次迭代都需要一个新列表。
-
可以分享一下文本文件的大小吗?
-
您为 JVM 分配的内存是多少?您是如何创建地图的(您应该传递 1,500,000 的初始大小以避免不断重新散列)。此外,如果您无法分配更多内存,使用 int[] 而不是 List
会节省大量内存。 -
@JBNizet 我知道,事实上我在帖子中说过,一个简单的解决方案是在 while 中声明一个新列表,但随后 --> GC 开销。我想知道是否有可能使用一个“新”并重复使用相同的列表。
-
@SanjeevSaha 3,04GB
标签: java arraylist reference garbage-collection overhead