首先,您可能已经知道了几件事,但对于了解这种情况很重要:程序使用的大部分内存是 JVM堆
。当程序开始执行时,堆具有初始大小。有时,JVM会要求OS提供更多内存并增加堆的大小。JVM还将执行垃圾回收,从而释放堆中的空间。
当使用的堆大小减小时,JVM不一定会释放内存。 oracle JVM不愿意这样做。例如,如果您的程序在启动时使用500
MB的ram,则在垃圾回收仅将100 MB用于其大部分执行之后,您不能假定会将额外的400 MB分配给操作系统。
此外,诸如Windows任务管理器之类的工具(我假设为unix的工具
ps) 将显示分配给JVM的所有内存的大小,而不管该内存是否被实际使用
。诸如jvisualvm之类的工具将使您确切地了解Java程序中的内存使用方式,尤其是您实际使用的堆数量与分配的数量。
考虑到这一点,我在以下情况下测试了您的程序。请注意,这取决于许多因素,包括使用的JVM,其版本以及可能的操作系统。
- 标准Java(SE)与Spring。
- 垃圾收集(GC)与无垃圾收集(NOGC)(我从jvisualvm调用了垃圾收集器)。
- 为JVM定义的最小堆大小(使用-Xmx8M)。这告诉JVM在启动时仅分配8MB。我的系统上的默认值为256MB。
对于每种情况,我都会报告分配的堆大小和使用的堆大小。这是我的结果:
- SE,NOGC,256M:已分配270 MB,已使用30 MB
- 春季,NOGC,256M:已分配270 MB,已使用30 MB
这些结果是相同的,因此根据您的问题,我认为您已经拥有与我以前不同的环境。
- SE,GC,256M:已分配270 MB,已使用9 MB
使用GC可以减少堆使用量,但是分配的内存仍然相同
- SE,NOGC,8M:已分配9 MB,已使用<5 MB
- 春季,NOGC,8M:已分配20 MB,已使用<5 MB
这是最重要的结果:分配更多的内存,因为在启动过程中某个时刻Spring可能需要更多的内存。
结论:
- 如果您想减少堆的使用,那么使用spring应该不会有太大问题。开销不是巨大的。
- 如果您尝试减少分配的内存,那么在本实验中,使用Spring的代价会更高。但是您仍然可以配置JVM,以使其比默认情况更多地释放内存。我对此了解不多,但是诸如jvm之类的选项
-XX:MaxHeapFreeRatio=70
可能只是一个开始(更多信息请参见http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html#PerformanceTuning)



