以下是我需要解决的方案.我有两个解决方案.
我需要维护从数据库获取的数据缓存,以便在Swing GUI上显示.每当我的JVM内存超过其分配内存的70%时,我需要警告用户过度使用.一旦JVM内存使用率超过80%,我就必须暂停所有数据库查询并清理作为用户操作的一部分提取的现有缓存并通知用户.在清理过程中,我将手动处理基于某些规则删除一些数据并指示JVM用于GC.每当GC发生时,如果内存清理并达到分配内存的60%,我需要重新启动所有数据库处理并将控制权交还给用户.
为了检查JVM内存统计信息,我发现了两个解决方案.无法决定哪种方式最好,为什么.
Runtime.freeMemory() - 创建的线程每10秒运行一次并检查可用内存,如果内存超出上述限制,必要的弹出窗口将会使用户熟悉并调用方法来暂停操作并释放内存.
MemoryPoolMXBean.getUsage() - Java 5引入了JMX以在运行时获取内存的快照.在,JMX我不能使用阈值通知,因为它只会在内存达到/超过给定的阈值时通知.唯一可以使用的方法是在MemoryMXBean中轮询并检查一段时间内的内存统计信息.
在使用轮询的情况下,对我来说似乎两个实现都是相同的.
请提出方法的优点,以及是否有任何其他替代方法/使用方法的任何更正.
只是旁注:Runtime.freeMemory()
没有说明分配剩余的内存量,它只是当前分配的内存中可用的内存量(最初小于VM配置使用的最大内存量),但是增长随着时间的推移.
启动VM时,max memory(Runtime.maxMemory()
)仅定义VM可以分配的内存上限(可使用-Xmx VM选项进行配置).总内存(Runtime.totalMemory()
)是为VM进程分配的内存的初始大小(可使用-Xms VM选项进行配置),并且每次分配超过当前空闲部分(Runtime.freeMemory()
)时将动态增长,直到达到最大记忆.
您感兴趣的指标是可用于进一步分配的内存:
long usableFreeMemory= Runtime.getRuntime().maxMemory() -Runtime.getRuntime().totalMemory() +Runtime.getRuntime().freeMemory()
要么:
double usedPercent=(double)(Runtime.getRuntime().totalMemory() -Runtime.getRuntime().freeMemory())/Runtime.getRuntime().maxMemory()
处理这类事情的常用方法是使用WeakReference
s和SoftReference
s.你需要同时使用两者 - 弱引用意味着你没有持有多个东西副本,而软引用意味着GC会挂起,直到它开始耗尽内存.
如果需要进行其他清理,则可以添加对队列的引用,并覆盖队列通知方法以触发清理.这一切都很有趣,但你确实需要了解这些课程的作用.
对于JVM来说,内存使用率达到100%是完全正常的,并且在GC之后它们会回复10%并且每隔几秒就会这样做.
您不应该尝试以这种方式管理内存.在运行完整的GC之前,您无法确定要保留多少内存.
我建议你弄清楚你真正想要实现的目标,并以另一种方式看待问题.