在64位JVM(对比32位)上运行相同的Spring Boot应用程序时,内存使用率会大大提高。
对于下面的示例Eureka应用程序,32位JVM使用大约100 MB的RAM,而64位JVM使用大约700 MB的RAM。在同一台计算机上运行多个微服务开始成为一个问题。
有谁知道造成这种情况的原因是什么?最重要的是,我们如何消除过多的内存使用?
以下示例是我们的Eurkea服务器的精简版本,但它与我们所有的Spring Boot微服务一起发生。
java源代码:
@SpringBootApplication
@EnableEurekaServer
public class Eureka_SpringMVC {
public static void main(String[] args) {
ConfigurableApplicationContext context = new SpringApplicationBuilder(Eureka_SpringMVC.class).headless(false).run(args);
}
}
Maven pom:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ca.twosd.tcms</groupId>
<artifactId>TCMS_Web_Eureka</artifactId>
<version>1.0.0</version>
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-parent</artifactId>
<version>Camden.SR6</version> <!-- Name of release train -->
</parent>
<dependencies>
<dependency>
<!-- Setup Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<!-- Setup Spring MVC & REST, use Embedded Tomcat -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<!-- Spring Cloud starter -->
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter</artifactId>
</dependency>
<dependency>
<!-- Eureka for service registration -->
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
</dependencies>
<properties>
<start-class>ca.eurekatest.Eureka_SpringMVC</start-class>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
谢谢!
答案 0 :(得分:2)
jvm使用多少堆大小不仅取决于jvm版本,还取决于运行jvm的机器。唉,我没有找到相关的规格。
我曾经遇到过在Google容器引擎上的kubernetes中运行在docker容器中的java进程的问题,当在具有54GB RAM的Google Compute Engine上运行时,jvms可以获取高达16GB的内存。当主机上运行大量容器时,这肯定太过分了。
不同本地计算机上的相同程序使用的内存要少得多。要查明默认情况下java程序在计算机上使用多少内存,请运行以下命令:
java -XX:+PrintFlagsFinal -version | grep -i heapsize
在我的16GB内存的机器上打印:
uintx ErgoHeapSizeLimit = 0 {product}
uintx HeapSizePerGCThread = 87241520 {product}
uintx InitialHeapSize := 268435456 {product}
uintx LargePageHeapSizeThreshold = 134217728 {product}
uintx MaxHeapSize := 4294967296 {product}
java version "1.8.0_131"
Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)
因此JVM最多占用可用内存的四分之一。尝试使用32位和64位版本,你可能会看到差异。
为了防止这种过多的内存声明,请始终使用至少-Xmx
参数启动jvm,例如:
java -Xmx512m -XX:+PrintFlagsFinal -version | grep -i heapsize
现在显示:
uintx ErgoHeapSizeLimit = 0 {product}
uintx HeapSizePerGCThread = 87241520 {product}
uintx InitialHeapSize := 268435456 {product}
uintx LargePageHeapSizeThreshold = 134217728 {product}
uintx MaxHeapSize := 536870912 {product}
java version "1.8.0_131"
Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)
您会看到MaxHeapSize值的差异。有关java选项can be found here
的更多信息