如何减少Spring内存占用

我想问你如何(或IF)可以减少Spring框架的RAM占用空间。

我创建了一个简单的helloworld应用程序来演示这个问题。 只有两个类和context.xml文件:

  • Main类 – 主要方法
  • Test类用于模拟一些“工作”(无限循环中的printig Hello)

context.xml仅包含以下内容:

  

Test类只包含名为init metod,在构造后调用:

 @Component public class Test{ @PostConstruct public void init() { Thread t = new Thread(new Runnable() { @Override public void run() { try { while (true) { System.out.println("Hello " + Thread.currentThread().getName()); Thread.sleep(500); } } catch (InterruptedException ex) { ex.printStackTrace(); } } }); t.start(); } } 

我准备了两个场景,在这两个场景中, main方法只包含一行。

在第一个场景中,main方法执行此操作: (new Test()).init(); 应用程序没有Spring工作,只消耗aprox。 8MB的RAM。

在第二个场景中,main方法包含以下内容: new ClassPathXmlApplicationContext(new String[]{"spring/context.xml"}); 因此,应用程序通过Spring容器初始化并消耗aprox。 45MB内存!

有没有办法如何减少(在最好的情况下完全摆脱)这个额外的内存? 到目前为止,我无法找到任何合适的解决方案。

我不介意启动时是否有额外的内存消耗 – 这很好,但在那之后,我需要我们的应用程序来减少它。

(这个问题背后的故事有点复杂,但这对我来说现在是核心问题。)

谢谢

首先,您可能已经知道但对了解情况很重要:程序使用的大部分内存是JVM堆 。 程序开始执行时,堆具有初始大小。 有时,JVM会向操作系统请求更多内存并增加堆的大小。 JVM还将执行垃圾收集,从而释放堆中的空间。

当使用的堆大小减小时,JVM不一定释放内存。 oracle JVM不愿意这样做。 例如,如果您的程序在启动时使用500 MB的ram,那么在垃圾收集仅在其大部分执行时使用100 MB时,您不能假设额外的400 MB将被返回给您的操作系统。

此外,像Windows任务管理器(我假设unix的ps )这样的工具将显示分配给JVM的所有内存的大小,无论该内存是否实际使用 。 像jvisualvm这样的工具可以让你准确地看到java程序中内存的使用方式,特别是你实际使用的堆数量与分配的数量。


考虑到这一点,我在以下场景中测试了您的程序。 请注意,这取决于许多因素,包括您使用的JVM,版本以及可能的操作系统。

  • 标准java(SE)vs Spring。
  • 垃圾收集(GC)与无(NOGC)(我称之为jvisualvm的垃圾收集器)。
  • 为JVM定义的最小堆大小(使用-Xmx8M)。 这告诉JVM在启动时只分配8MB。 我系统的默认值是256MB。

对于每种情况,我都会报告分配的堆大小和使用的堆大小。 这是我的结果:

  • SE,NOGC,256M:分配270 MB,使用30 MB
  • Spring,NOGC,256M:分配270 MB,使用30 MB

这些结果是相同的,所以根据你的问题,我假设你已经拥有了与我不同的环境。

  • SE,GC,256M:分配270 MB,使用9 MB

使用GC可以减少堆使用量,但我们仍然拥有相同的分配内存

  • SE,NOGC,8M:分配9 MB,<5 MB使用
  • Spring,NOGC,8M:分配20 MB,<5 MB使用

这是最重要的结果:分配了更多内存,因为Spring在启动期间可能需要更多内存。

结论:

  • 如果您正在尝试减少堆使用量,那么使用spring应该不是什么大问题。 开销并不大。
  • 如果你试图减少分配的内存,在这个实验中使用Spring的价格会更陡峭。 但您仍然可以配置JVM,以便它比默认更频繁地释放内存。 我对此-XX:MaxHeapFreeRatio=70 ,但是诸如-XX:MaxHeapFreeRatio=70类的jvm选项可能是一个开始(更多信息请参见http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102 .html#PerformanceTuning )