2017-04-24 81 views
0

在64位JVM(vs 32位)上运行相同的Spring Boot应用程序时,内存使用率显着提高。Spring引导在64位JVM上使用大量内存

对于下面的示例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

我已经尝试将Brixton.SR7和Camden.SR6的spring-cloud-starter-parent升级为没有任何明显改进。 – HeavyE

回答

2

jvm使用的堆大小不仅取决于jvm版本,还取决于运行jvm的机器。唉,我没有找到这个规格。

我曾经遇到过在Google Container Engine上运行在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

+1

如果有人正在使用Windows Powershell进行相同的检查,则该命令为: java -XX:+ PrintFlagsFinal -version |选择字符串 - 模式“堆积” – HeavyE