考虑一个 java 进程,其中主线程从源读取 Json 对象,并将具有读取的 Json 对象的任务分配给具有 5 个工作线程的 FixThreadPoolExecutor。
这里的问题是,读取 Json 的源比工作线程完成任务的速度快得多。因此,当 Json 在内存中累积等待工作线程时,会抛出 OutOfMemoryException。这里工作线程的数量不能增加。
那么以下内容是解决内存不足问题的有效解决方案吗?
在主线程中检查可用内存的百分比,如果内存使用率超过 80%,则 hibernate 一段时间
main(){
for(;;){
//read the data and assign to executor
long total = Runtime.getRuntime().maxMemory(),free = Runtime.getRuntime().freeMemory()
float usedPersent = (total-free)*100/total
if(usedPercent > 80)
Thread.sleep(2000);
}
}
有好的做法吗?
最佳答案
您应该通过正确的设计而不是黑客手段来解决 OOME 问题。您的 JSON 对象应被推送到有界阻塞队列中,该队列将自动负责对生产者应用“背压”。
一个更简洁的选择是重新设计,以便为每个提交的任务提供要处理的加载 JSON 的一部分,这样它就不会自行提取任何内容。这样,您甚至不需要实现队列:您依赖于执行程序服务内部的队列,您只需要适当配置即可。例如,使用显式 ThreadPoolExecutor 构造函数,向其传递 CallerRunsPolicy
作为拒绝政策。
另请注意,提前加载过多的 JSON 会降低系统整体速度,因为多余的对象将被提升到老一代,从而增加主要垃圾收集的频率。
关于java - 这是缓解 OutOfMemoryError 的好习惯吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20396098/