5

We have an application based on Spring Boot. We deploy it using an executable jar which is about 20Meg. When we start this application, it uses 18Gigs worth of "Virutual" memory right away. I understand that most of this is kept in secondary storage such as hard disk, but our System Administrators are questioning why we need so much of Virtual memory.

The Jar file is small. At the startup I am using BoneCPDataSource but I've cut down # of connections to 5. As soon as application is started it uses 18g of Virtual memory.

Can someone tell me why? Should I play with java memory settings on command line to reduce this number? The command we use is:

java -jar filename.jar

As requested, here's some more info:

1) Here's a line from 'top' command:

24511 xyz 20 0 17.6g 531m 9.8m S 0.0 0.8 0:16.57 java

2) There's no Neo4J. Here's my pom.xml

http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0

<groupId>com.xyz.myapp</groupId>
<artifactId>myapp-rest-service</artifactId>
<version>0.1.0</version>

<properties>
    <start-class>com.xyz.myapp.rest.Application</start-class>
</properties>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.0.1.RELEASE</version>
</parent>

<dependencies>
    <dependency>
        <groupId>com.jolbox</groupId>
        <artifactId>bonecp</artifactId>
        <version>0.8.0.RELEASE</version>
        <exclusions>
            <exclusion>
                <groupId>com.jolbox</groupId>
                <artifactId>com.jolbox.logging</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>4.0.3.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</artifactId>
        <version>4.0.3.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-api</artifactId>
        <version>2.0-rc1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.0-rc1</version>
    </dependency>
    <dependency>
        <groupId>oracle</groupId>
        <artifactId>jdbc</artifactId>
        <version>6.0</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-bundle</artifactId>
        <version>1.18.1</version>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin> 
            <artifactId>maven-compiler-plugin</artifactId> 
            <version>2.3.2</version> 
        </plugin>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

<repositories>
    <repository>
        <id>spring-snapshots</id>
        <url>http://repo.spring.io/libs-snapshot</url>
        <snapshots><enabled>true</enabled></snapshots>
    </repository>
</repositories>

<pluginRepositories>
    <pluginRepository>
        <id>spring-snapshots</id>
        <url>http://repo.spring.io/libs-snapshot</url>
        <snapshots><enabled>true</enabled></snapshots>
    </pluginRepository>
</pluginRepositories>

3) I build this application using following command:

mvn clean package

and this is what it creates in the ./target directory:

-rwxr-xr-x 1 myuserid Domain Users 20259555 Jun 9 15:36 myapp-rest-service-0.1.0.jar

4) lsof output for my app:

http://pastebin.com/V00BrD67

5) Output from mvn dependency:tree

http://pastebin.com/cFnR0NMX

DilTeam
  • 2,551
  • 9
  • 42
  • 69
  • I find that difficult to believe, unless you're using something like Neo4J that mmaps large data sets. There's not nearly enough detail, however; at a minimum to start, we'd need to see all the memory information for the application, especially including the resident set. – chrylis -cautiouslyoptimistic- Jun 09 '14 at 22:13
  • The fact that you have such a big discrepancy there strongly indicates that something is getting mmapped in early. The next step I'd take is to run lsof and see if any such large files are open. – chrylis -cautiouslyoptimistic- Jun 09 '14 at 22:48
  • You are aware that you are mixing spring versions? Spring boot uses 4.0.3 whereas you are using 2jars from 3.2.4, you should never mix versions of frameworks, this will lead to trouble. Could you add your full pom instead of only the dependencies? – M. Deinum Jun 10 '14 at 12:03
  • Please add the output of `mvn dependency:tree`. To troubleshoot you probably want to add a memory profiler to the app to see what is taking up the memory. Also you are using `spring-boot-starter-actuator` which by default keeps metrics in-memory, might be worth to see what happens without the actuator. – M. Deinum Jun 10 '14 at 12:06
  • As requested, added entire pom.xml & output from mvn dependency:tree. Removing 'actuator' didn't help. I am profiling using pmap. Lots of 'annon' processes & quite a few jvm related libraries. Will keep looking. Thanks for everyone's help. – DilTeam Jun 10 '14 at 18:19

2 Answers2

7

After specifying -Xmx option, the virtual memory consumption went down. Currently, I am starting my Spring Boot app like this:

java -Xmx4096m -jar myapp-rest-service-0.1.0.jar

If there's a better way to set this value in application.properties file (or somewhere else), please do let me know.

try-catch-finally
  • 7,436
  • 6
  • 46
  • 67
DilTeam
  • 2,551
  • 9
  • 42
  • 69
4

JVM uses default heap size based on the physical memory available (usually a percentage of available system memory). The value also depends on the JVM version and the client/server mode.

You can find more about this topic with these keyword: "default Java heap configuration"

This SO answer addresses the same topic (Jabir's answer): What is the default maximum heap size for Sun's JVM from Java SE 6?

halfer
  • 19,824
  • 17
  • 99
  • 186
Steve Oh
  • 1,149
  • 10
  • 18