当前位置: 首页 > 面试题库 >

如何减少Spring内存占用

花和宜
2023-03-14
问题内容

我想问你如何减少Spring框架的RAM占用量。

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

  • Main -主要方法课
  • Test -用于模拟某些“工作”的类(无穷循环中的printig Hello)

context.xml 仅包含以下内容:

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

测试类仅包含称为的方法init,构造后会调用:

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

在第一种情况下,主要方法是这样做的:(new Test()).init();
App在没有Spring的情况下工作,并且仅消耗aprox。8MB的RAM。

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

有什么办法可以减少(最好是完全摆脱掉)这个额外的内存吗?到目前为止,我还找不到任何合适的解决方案。

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

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

谢谢


问题答案:

首先,您可能已经知道了几件事,但对于了解这种情况很重要:程序使用的大部分内存是 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)


 类似资料:
  • 我正在使用spring boot开发客户端应用程序。在运行spring boot应用程序(使用完全可执行的jar)时,x64服务器的内存占用约为190M,x86服务器的内存占用约为110M。 我的jvm选项是(-xmx64m-xms64m-xx:maxpermsize=64m-server),为什么在x64服务器中,内存占用这么大?如何将内存使用量降低到150M以下? 多谢了。

  • 我有一个Java程序可以在Solaris 10 X86上运行,具有2GB物理内存和2GB交换。 该程序在64位Linux中运行良好,仅消耗约450MB内存。 然而,当它在Solaris中运行时,它总是报告OutOfMemoryError,我注意到在错误发生之前,它正试图使用 那么为什么JVM会尝试使用那么多虚拟内存呢?有没有办法告诉JVM不要使用那么多虚拟内存? 谢谢你。 编辑: 谢谢大家的意见!

  • 我有一个问题,为什么非常简单的Spring Boot应用程序分配100 MB内存?如何减少内存使用? 1) https://start.spring.io/生成带有“Spring Web Starter”依赖项的演示程序 2) Dockerfile pom.xml 类 1) 记忆测试1 Docker build-f Dockerfile-t demo. docker run-p 8080:8080

  • 本文向大家介绍详解如何减少python内存的消耗,包括了详解如何减少python内存的消耗的使用技巧和注意事项,需要的朋友参考一下 Python 打算删除大量涉及像C和C++语言那样的复杂内存管理。当对象离开范围,就会被自动垃圾收集器回收。然而,对于由 Python 开发的大型且长期运行的系统来说,内存管理是不容小觑的事情。 在这篇博客中,我将会分享关于减少 Python 内存消耗的方法和分析导致

  • 问题内容: 我一直在为OpenGL练习编写Minecraft副本(据我估计很多),但是在编写了基本的渲染API之后,我注意到真正的Minecraft 占用了 大量 内存或内存- 大约800MB!我完全可以理解为什么它必须记住所有的块,以及生成器的小怪和地形数据……我问自己:“此块与该块完全相同。它们可以在代码中吗? ” 并记得C ++有指针,所以我试图用我能想到的唯一方法在Java中做同样的事情,

  • 问题内容: 背景 我有一个Spring批处理程序,该程序读取一个文件(我正在使用的示例文件的大小约为4 GB),对该文件进行少量处理,然后将其写到Oracle数据库中。 我的程序使用1个线程读取文件,并使用12个工作线程进行处理和数据库推送。 我正在搅动很多年轻一代的记忆,这使我的程序运行得比我想象的要慢。 建立 JDK 1.6.18 春季批处理2.1.x 4核计算机,带16 GB内存 问题 使用