Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何减少Spring内存占用_Java_Spring_Ram - Fatal编程技术网

Java 如何减少Spring内存占用

Java 如何减少Spring内存占用,java,spring,ram,Java,Spring,Ram,我想问您如何(或是否)减少Spring框架的RAM占用 我创建了一个简单的helloworld应用程序来演示这个问题。只有两个类和context.xml文件: Main-使用Main方法初始化 Test-用于模拟某些“工作”的类(无限循环中的printig Hello) context.xml仅包含以下内容: <context:component-scan base-package="mypackage" /> 我准备了两个场景,其中mainmethod只包含一行 在第一个场景

我想问您如何(或是否)减少Spring框架的RAM占用

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

  • Main
    -使用Main方法初始化
  • Test
    -用于模拟某些“工作”的类(无限循环中的printig Hello)
context.xml
仅包含以下内容:

<context:component-scan base-package="mypackage" />
我准备了两个场景,其中
main
method只包含一行

在第一个场景中,main方法执行以下操作:
(newtest()).init()
应用程序在没有Spring的情况下工作,只使用aprox。8MB内存

在第二个场景中,main方法包含以下内容:
newclasspathXMLApplicationContext(新字符串[]{“spring/context.xml”})
因此,应用程序通过Spring容器初始化,并使用aprox。45MB内存

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

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

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


首先感谢您

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

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

此外,诸如windows任务管理器(我假设unix的
ps
之类的工具将显示分配给JVM的所有内存的大小,而不管该内存是否实际使用。像这样的工具可以让您确切地了解java程序中内存的使用情况,特别是实际使用的堆数量与分配的堆数量


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

  • 标准java(SE)vs Spring
  • 垃圾收集(GC)与无(NOGC)(我从jvisualvm中调用了垃圾收集器)
  • 为JVM定义的最小堆大小(使用-Xmx8M)。这告诉JVM在启动时只分配8MB。我的系统的默认值是256MB
对于每种情况,我报告分配的堆大小和使用的堆大小。以下是我的结果:

  • SE,NOGC,256M:已分配270MB,已使用30MB
  • Spring,NOGC,256M:270MB已分配,30MB已使用
这些结果是相同的,所以从你的问题来看,我假设你已经有了一个与我不同的环境

  • SE,GC,256M:270MB已分配,9MB已使用
使用GC可以减少堆的使用,但是我们仍然有相同的分配内存


  • SE,NOGC,8M:9MB分配,你是如何测量内存消耗的?如果你想使用Spring作为DI容器,我建议你尝试一些更轻量级的东西,比如Guice或Dagger。这只是一个想法,(我不知道它是否有效):我想,你可以减少内存占用(PermGen)当您使用基于java的spring配置而不是xml配置时,因为我希望spring不会加载用于读取文件的xml库。@injecteer我使用的是windows任务管理器,因为实际分配的内存是对我来说唯一重要的内存。还有其他我用的东西JProfiler@Ralph谢谢你的提示,我会尝试一下,谢谢你详尽的回答。我的测量是在Win7上完成的,Oracle JVM 1.7 32位。我非常了解Java中的这些理论内存,VM选项也是如此(VM tunning是我们做的第一件事)。我实际上在使用JProfiler进行评测。我关心的唯一内存消耗是分配的数量。例如,Spring任务管理器说,它消耗了45M,Jprofiler说堆有125M(使用了21M,在Spring的hashmaps中使用了反射字符串),而没有Spring任务管理器说,它消耗了10M,Jprofiler说堆有122M(使用了7M)。你的最后一点最适合我的问题,我来看看,如果我没有错过什么,那么,进一步调整VM,我仍然有8米没有Spring和28米(15+M改进,但仍然太多)。根据JProfiler的说法,使用的堆空间是3M(没有弹簧的情况下为1,5M,这并不是什么区别),但非堆空间是8M(没有弹簧的情况下为1M)。有没有可能减少这个问题?对不起,伙计,这个问题已经过了一段时间了。见我最后的评论。我想我没什么进展了。
    @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();
        } 
    }