我有一个mysql数据库,它填充了一个包含带时间戳(长)和对象(safeboxForLongString)的Map的对象。
safebox中的字符串大小为5-15MB。
我的问题是,在从服务器请求字符串数据约30分钟后,我的RAM内存已经是11-12 GB。我已经尝试调用System.gc并清除以前填充的TreeMap。但没有成功。
支持数据库的目的不是我不必使用我的所有内存吗?
我无法完成收集服务器数据的过程,因为我总是在那个问题上失败。请帮帮我。
这里是相关代码
//fill the Database
Main.getAllAvailableEntries().forEach(entryName -> {
final long[] id = {0};
treeMapWrapperRepo.findAll().forEach(entry -> {
if (entry.getCurrency().equals(entryName)) {
id[0] = entry.getMultiHashMapWrapper_id();
}
});
if (id[0] == 0) {
System.out.println("Forming: " + entryName);
final TreeMapWrapper treeMapWrapper = new TreeMapWrapper(entryName);
TreeMap<Long, SafeBoxForLongString> timeStampToSafeBoxMap = new TreeMap<>();
int start = startDateInThePast;
while (start - length >= 0) {
long startDate = instant.minus(start, ChronoUnit.DAYS).getEpochSecond();
long endDate = instant.minus(start - length, ChronoUnit.DAYS).getEpochSecond();
String getReponseWith45DaysLength = dataController.getDataForDB(entryName, startDate, endDate, String.valueOf(resolution));
while (getReponseWith45DaysLength.isEmpty()) {
getReponseWith45DaysLength = dataController.getDataForDB(entryName, startDate, endDate, String.valueOf(resolution));
}
SafeBoxForLongString safeBoxForLongString = new SafeBoxForLongString(getReponseWith45DaysLength);
safeBoxForLongString.setMultiHashMapWrapper(treeMapWrapper);
timeStampToSafeBoxMap.put(startDate, safeBoxForLongString);
treeMapWrapper.setLongSafeTimeAndReponseMap(timeStampToSafeBoxMap);
start--;
}
treeMapWrapperRepo.save(treeMapWrapper);
treeMapWrapper.getLongSafeTimeAndReponseMap().clear();
System.gc();
}
});
编辑:就像一个堆栈器说的那样,treeMapWrapperRepo.findAll()。是问题。
答案 0 :(得分:1)
我看到的错误很少。首先,您要从数据库中检索所有条目。这些条目将直接从磁盘(DB)加载到RAM(Java对象)。
然后,垃圾收集器查看未引用/分离的对象。知道了这一点,我重构代码并在存储库端使用分页来一次加载10个项目或任何其他合适的值。不要将所有检索到的对象存储在列表中,只存储您需要的对象。您可以通过将变量设置为null来为GC提供提示。
另外,我不确定Main.getAllAvailableEntries()
从何处获取数据。问题可能出在那里而不是treeMapWrapperRepo.findAll()
。
正如Dominik在评论中所建议的那样,尝试使用Profiler和调试器。这将为您提供泄漏记忆的提示。