当前位置: 首页 > 知识库问答 >
问题:

Spring启动消耗太多内存

鲁鸿
2023-03-14

我在spring boot中创建了一些服务,我有11个fat jars,我将它们部署在docker容器中,我怀疑每个jar在没有任何使用的情况下消耗了1到1.5 GB的RAM,我通过运行以下命令来检查RAM:

docker stats containername

起初我以为是java容器,我试图改成一个使用alpine的容器,但没有任何变化,所以我认为唯一的问题是我的罐子。有没有办法更改罐子正在使用的 RAM?或者这种行为是正常的,因为每个罐子都有一个嵌入的雄猫?或者也许最好将一些罐子放在一起并将它们部署为战争,只使用一只雄猫作为一组“罐子”?有人可以分享他/她的经验吗?

先谢谢你。

共有3个答案

顾英发
2023-03-14

在查看了openjkd DockerHub映像文档之后,似乎可以通过设置< code>-XX:MaxRAM=来设置默认的堆大小...:

Windows服务器容器支持RAM限制,但目前JVM无法检测到它。为了防止过多的内存分配,-XX:MaxRAM=...选项必须用不大于容器RAM限制的值来指定。

来自预言机文档:

默认堆大小除非在命令行上指定初始和最大堆大小,否则它们是根据机器上的内存量计算的。

司空俊雅
2023-03-14

您可以使用-e JAVA_OPTS=“-Xmx64M-Xms64M”设置docker容器的内存使用情况。

码头工人文件:

FROM openjdk:8-jre-alpine
VOLUME ./mysql:/var/lib/mysql
ADD /build/libs/application.jar app.jar
ENTRYPOINT exec java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar

映像运行:

 docker run -d --name container-name -p 9100:9100 -e JAVA_OPTS="-Xmx512M -Xms512M"   imagename:tag

在这里我设置512Mb内存使用情况。您可以设置1g或根据您的要求。使用此功能运行后检查您的内存使用情况。它将最大512Mb。

柳修为
2023-03-14

这是Java通常的行为方式。JVM需要你给它多少内存,它就会执行一个叫做垃圾收集的过程(Java中的垃圾收集器是什么)来释放空间,一旦它决定这样做。

但是,如果您不告诉 JVM 它可以使用多少内存,它将使用系统默认值,这取决于您的系统内存和您拥有的内核数量。您可以使用以下命令(如何确定缺省 Java 堆大小)进行验证:

java -XX:+PrintFlagsFinal -version | grep HeapSize

在我的机器上,初始堆内存为256MiB,最大堆大小为4gb。然而,这并不意味着您的应用程序需要它。

测量内存的一个好方法是使用jVisual alvm等监控工具。此外,您还可以使用执行器的/Healthendpoint来查看堆内存使用情况。

堆内存使用情况通常具有锯齿模式(为什么是锯齿形图形),其中内存逐渐被使用,并最终由垃圾回收器释放。

垃圾收集后剩余的内存通常是无法销毁的对象,因为它们仍在使用中。你可以把这看作是你的工作记忆。现在,要配置-Xmx,您必须在试用后查看应用程序的行为:

  • 将其配置为低于正常内存使用,您的应用程序将内存溢出,引发OutOfMemoryError
  • 将其配置得太低,但高于最低内存使用量,您将看到性能受到巨大影响,因为垃圾收集器必须不断释放内存。
  • 配置太高,你会保留在大多数情况下不需要的内存,因此浪费了太多资源。

从上面的屏幕截图中,您可以看到我的应用程序为堆使用保留了大约1GiB的内存,而在垃圾收集之后,它只使用了大约30MiB的内存。这意味着它的-Xmx值太高,因此我们可以将其更改为不同的值,并查看应用程序的行为。

人们通常更喜欢2次方工作(尽管没有限制,如jvm堆设置模式所示)。在我的例子中,我需要至少使用30MiB,因为这是我的应用程序始终使用的内存量。这意味着我可以尝试-Xmx32m,看看它的性能如何,并在内存溢出或性能更差时进行调整。

 类似资料:
  • Android Studio在Mac机上消耗了太多的内存,并且还运行了多java进程。 Android Studio版本:使用Android Studio北极狐2020.3.1(补丁1构建#AI-203.7717.56.2031.7621141,构建于2021年8月7日) 当我面临内存不足的问题时,我正在监视Android Studio的内存消耗,我注意到多个“Java”进程正在运行,甚至一个进程

  • 我一直在测试许多开源动画-GIF库,以便将文件加载到我们的项目中。 它们中的大多数声称是高性能库,然而,每当我加载动画gif时,我的应用程序就会使用大约8MB的内存。 问题是,这个专用内存空间似乎永远不会被释放。我们可以看到它线性增长: 这让我怀疑我在这里做的是否正确。这种行为是正确的,还是对用户有潜在的不良影响?

  • 我需要以下令牌: 允许的字符包括大写、小写、数字、空格和连字符 长度不固定(长度必须至少为两个字符) 标记必须至少包含一个空格或连字符 令牌必须以大写、小写、数字、空格或连字符开头和结尾(不能以空格开头或结尾) 下面语法中的ANTLR lexer规则“alphanumericspacehyphen”除了一个情况外几乎都起作用。使用解析器规则“sic”进行测试,以下输入将解析(不带引号): 以下输入

  • 问题内容: 我试图检查Go如何处理100,000个goroutine。我写了一个简单的程序来产生许多例程,除了打印一些公告外什么也不做。我将MaxStack大小限制为只有512个字节。但是我注意到程序的大小并没有因此而减少。它消耗了大约460 MB的内存,因此每个goroutine消耗了大约4 KB的内存。我的问题是,我们可以将goroutine的最大堆栈大小设置为低于“最小”堆栈大小(可能为4

  • 在我运行java应用程序之前,我的linux空闲内存为4942356KB,我的启动参数使用-xmx2048m和-xms2048m使最大堆内存和初始堆内存为2G,但我发现在我启动应用程序之后,我的linux系统空闲内存在一步一步地减少,而不是启动后总共消耗了2G内存,谁能告诉我原因和机制? 还有一个问题,我的jvm启动参数是,启动前的空闲内存是5g,1个小时后,我发现这个应用程序已经有14053个线

  • 问题内容: 具有100个属性的一个对象所消耗的存储空间是否与每个具有一个属性的100个对象所消耗的存储空间相同? 为一个对象分配多少内存? 添加属性时会使用多少额外空间? 问题答案: 指出,这不是一个容易回答的简单问题: JVM可以自由地以内部或大端或小端的任何方式存储数据,并具有一定的填充或开销,尽管基元必须表现得好像它们具有官方大小一样。 例如,JVM或本机编译器可能会决定将64位长块(如)存