如何减少Spring内存占用 [英] How to reduce Spring memory footprint

查看:223
本文介绍了如何减少Spring内存占用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I would like to ask you HOW (or IF) is possible to reduce Spring framework's RAM footprint.

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

I created a simple helloworld app for demonstrating the issue. There are only two classes and context.xml file:


  • Main - 包含的类主要方法

  • 测试 - 用于模拟某些工作的类(无限循环中的printig Hello)

  • Main - class with main method
  • Test - class used for simulating some "work" (printig Hello in endless loop)

context.xml 仅包含:

<context:component-scan base-package="mypackage" />

测试类只包含名为 init 的元文件,施工后调用:

Test class contains only metod called init, called after construction:

@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 方法只包含一行。

I prepared two scenarios and in both of them main method contains only one line.

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

In first scenario main method does this: (new Test()).init(); App works without Spring and consumes only aprox. 8MB of RAM.

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

In second scenario main method contains following: new ClassPathXmlApplicationContext(new String[]{"spring/context.xml"}); So the app is initialized throug Spring container and consumes aprox. 45MB of RAM !

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

Is there any way how to reduce (in best case completely get rid of) this extra memory ? So far I wasn't able to find any fitting solution.

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

I don't mind if there is the extra memory consumption on startup - this is perfectly fine, but after that, I need our app to reduce it.

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

(The story behind this question is a bit more complicated, but this is for me now the core problem.)

谢谢

推荐答案

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

First a few things which you may already know but are important to understand the situation: most of the memory your program uses is the JVM heap. The heap has an initial size when your program starts executing. Sometimes the JVM will ask the OS for more memory and increase the size of the heap. The JVM will also perform garbage collection, thus freeing space in the heap.

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

When the used heap size diminishes, memory is not necessarily released by the JVM. The oracle JVM is reluctant to do so. For example if your program uses 500 MB of ram on startup, then after garbage collection only uses 100 MB for most of its execution, you cannot assume the additional 400 MB will be given back to your OS.

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

Furthermore, tools like the windows task manager (and I assume unix's ps) will display the size of all the memory that is allocated to the JVM, regardless of whether this memory is actually used or not. Tools like jvisualvm will let you see exactly how the memory is used in your java program, and in particular what amount of heap you're actually using vs. how much is allocated.

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

With this in mind I tested your program in the following scenarios. Note that this depends on many factors including which JVM you use, its version, and probably your OS too.


  • 标准java(SE)vs Spring。

  • 垃圾收集(GC)与无(NOGC)(我从jvisualvm调用了垃圾收集器)。

  • 为JVM定义的最小堆大小(使用-Xmx8M)。这告诉JVM在启动时只分配8MB。我系统上的默认值是256MB。

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

For each case I report the allocated heap size and used heap size. Here are my results:


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

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

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

These results are identical, so from your question I assume you already had a different environment than I did.


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

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

Using the GC reduces heap usage, but we still have the same allocated memory


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

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

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

This is the most important result: more memory is allocated because Spring probably needs more at some point during startup.

结论:

  • If you're trying to reduce heap usage, using spring should not be much of a problem. The overhead is not gigantic.
  • If you're trying to reduce allocated memory, the price of using Spring, in this experiment, is steeper. But you can still configure your JVM so that it will free memory more often than the default. I don't know much about this, but jvm options such as -XX:MaxHeapFreeRatio=70 might be a start (more here http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html#PerformanceTuning )

这篇关于如何减少Spring内存占用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆