Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions out-of-memory-sample/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Out-of-Memory-Samples

This sample project is used to show 3 types of circumstances under which out of memory exceptions occur in spring-boot
applications of Azure Spring Cloud.

- **Out of direct memory for violating JVM options**:
The direct memory space assigned as JVM options exhausted.

- **Out of on-heap memory for violating JVM options**:
The heap memory space assigned as JVM options exhausted.

- **Out of direct memory leading to system memory running out**:
Direct memory being requested constantly, the increasement of direct memory exhausted pod memory so that system memory
runs out.


49 changes: 49 additions & 0 deletions out-of-memory-sample/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<artifactId>memory-out</artifactId>
<build>
<plugins>
<plugin>
<artifactId>spring-boot-maven-plugin</artifactId>
<groupId>org.springframework.boot</groupId>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<artifactId>spring-boot-starter</artifactId>
<groupId>org.springframework.boot</groupId>
</dependency>

<dependency>
<artifactId>spring-boot-starter-test</artifactId>
<groupId>org.springframework.boot</groupId>
<scope>test</scope>
</dependency>
<dependency>
<artifactId>spring-boot-starter-web</artifactId>
<groupId>org.springframework.boot</groupId>
</dependency>
<dependency>
<artifactId>spring-boot-starter-actuator</artifactId>
<groupId>org.springframework.boot</groupId>
</dependency>
</dependencies>
<groupId>com.microsoft.azure.spring</groupId>
<modelVersion>4.0.0</modelVersion>
<name>memory-out</name>

<parent>
<artifactId>spring-boot-starter-parent</artifactId>
<groupId>org.springframework.boot</groupId>
<relativePath/>
<version>2.6.2</version> <!-- lookup parent from repository -->
</parent>
<properties>
<java.version>11</java.version>
</properties>

<version>0.0.1-SNAPSHOT</version>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See LICENSE in the project root for
* license information.
*/

package com.microsoft.azure.spring.sample;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class MemoryOutApplication {

public static void main(String[] args) {
SpringApplication.run(MemoryOutApplication.class, args);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See LICENSE in the project root for
* license information.
*/

package com.microsoft.azure.spring.sample;

import com.microsoft.azure.spring.sample.service.DirectMemoryOut;
import com.microsoft.azure.spring.sample.service.HeapMemoryOut;
import java.util.Timer;
import java.util.TimerTask;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MemoryOutController {

@RequestMapping("/")
public String home() throws Exception {
return "This is the demo for azure spring cloud OOM analysis.";
}

@RequestMapping("/heap-out")
public String heapOut() throws Exception {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
try {
HeapMemoryOut heapMemoryOut = new HeapMemoryOut();
heapMemoryOut.run();
} catch (Exception e) {
e.printStackTrace();
}
}
}, 100);
return "Now run the out of heap memory problem";
}

@RequestMapping("/direct-out")
public String directJvmOut() throws Exception {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
try {
DirectMemoryOut directMemoryOut = new DirectMemoryOut();
directMemoryOut.run();
} catch (Exception e) {
e.printStackTrace();
}
}
}, 100);
return "Now run the out of direct memory problem";
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See LICENSE in the project root for
* license information.
*/

package com.microsoft.azure.spring.sample.service;


import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;


public class DirectMemoryOut {

public void run() throws Exception {
try {
List<ByteBuffer> list = new ArrayList<ByteBuffer>();
for (int i = 0; ; i++) {
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(1024);
list.add(byteBuffer);
Thread.sleep(10);
if (i % 10 == 0) {
System.out.println(
"Using direct memory. Number " + i + " with memory usage:" + MemoryTools.printDirectMemory(
true));
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See LICENSE in the project root for
* license information.
*/

package com.microsoft.azure.spring.sample.service;

import java.util.ArrayList;
import java.util.List;

public class HeapMemoryOut {

public void run() {
try {
List<LongString> memoryHoldStringList = new ArrayList<>();
for (int i = 0; ; i++) {
LongString memory = new LongString("I am very big string for memory out. In Loop " + i + ". ");
memoryHoldStringList.add(memory);
Thread.sleep(10);
if (i % 10 == 0) {
System.out.println("Using on-heap memory. Finish loop:" + memoryHoldStringList.size());
MemoryTools.printMemory();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See LICENSE in the project root for
* license information.
*/

package com.microsoft.azure.spring.sample.service;

public class LongString {

private String value;

public LongString(String value) {
for (int i = 0; i < 100; i++) {
this.value += value;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See LICENSE in the project root for
* license information.
*/

package com.microsoft.azure.spring.sample.service;


import java.lang.management.ManagementFactory;
import java.lang.management.MemoryManagerMXBean;
import java.lang.management.MemoryPoolMXBean;
import java.util.Arrays;
import java.util.List;

public class MemoryTools {

public static void printMemory() {
Runtime runtime = Runtime.getRuntime();
double freeMemory = (double) runtime.freeMemory() / (1024 * 1024);
double totalMemory = (double) runtime.totalMemory() / (1024 * 1024);
double usedMemory = totalMemory - freeMemory;

System.out.println("Total Memory:" + totalMemory);
System.out.println("Free Memory:" + freeMemory);
System.out.println("Used Memory:" + usedMemory);

}


public static int printDirectMemory(boolean printInfo) {
List<MemoryPoolMXBean> memoryPoolMXBeans = ManagementFactory.getMemoryPoolMXBeans();
for (MemoryPoolMXBean bean : memoryPoolMXBeans) {
System.out.println(bean.getName() + ": " + bean.getUsage());
}
List<MemoryManagerMXBean> memoryManagerMXBeans = ManagementFactory.getMemoryManagerMXBeans();
for (MemoryManagerMXBean bean : memoryManagerMXBeans) {
System.out.println(bean.getName() + ": " + Arrays.asList(bean.getMemoryPoolNames()));
}
System.out.println();
return 0;

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@