diff --git a/out-of-memory-sample/README.md b/out-of-memory-sample/README.md new file mode 100644 index 0000000..e8ac8da --- /dev/null +++ b/out-of-memory-sample/README.md @@ -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. + + diff --git a/out-of-memory-sample/pom.xml b/out-of-memory-sample/pom.xml new file mode 100644 index 0000000..dcfbea2 --- /dev/null +++ b/out-of-memory-sample/pom.xml @@ -0,0 +1,49 @@ + + + memory-out + + + + spring-boot-maven-plugin + org.springframework.boot + + + + + + spring-boot-starter + org.springframework.boot + + + + spring-boot-starter-test + org.springframework.boot + test + + + spring-boot-starter-web + org.springframework.boot + + + spring-boot-starter-actuator + org.springframework.boot + + + com.microsoft.azure.spring + 4.0.0 + memory-out + + + spring-boot-starter-parent + org.springframework.boot + + 2.6.2 + + + 11 + + + 0.0.1-SNAPSHOT + + diff --git a/out-of-memory-sample/src/main/java/com/microsoft/azure/spring/sample/MemoryOutApplication.java b/out-of-memory-sample/src/main/java/com/microsoft/azure/spring/sample/MemoryOutApplication.java new file mode 100644 index 0000000..417660e --- /dev/null +++ b/out-of-memory-sample/src/main/java/com/microsoft/azure/spring/sample/MemoryOutApplication.java @@ -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); + } + +} diff --git a/out-of-memory-sample/src/main/java/com/microsoft/azure/spring/sample/MemoryOutController.java b/out-of-memory-sample/src/main/java/com/microsoft/azure/spring/sample/MemoryOutController.java new file mode 100644 index 0000000..6de06d0 --- /dev/null +++ b/out-of-memory-sample/src/main/java/com/microsoft/azure/spring/sample/MemoryOutController.java @@ -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"; + } + +} diff --git a/out-of-memory-sample/src/main/java/com/microsoft/azure/spring/sample/service/DirectMemoryOut.java b/out-of-memory-sample/src/main/java/com/microsoft/azure/spring/sample/service/DirectMemoryOut.java new file mode 100644 index 0000000..9cdaa34 --- /dev/null +++ b/out-of-memory-sample/src/main/java/com/microsoft/azure/spring/sample/service/DirectMemoryOut.java @@ -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 list = new ArrayList(); + 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(); + } + } +} + diff --git a/out-of-memory-sample/src/main/java/com/microsoft/azure/spring/sample/service/HeapMemoryOut.java b/out-of-memory-sample/src/main/java/com/microsoft/azure/spring/sample/service/HeapMemoryOut.java new file mode 100644 index 0000000..ec4ed62 --- /dev/null +++ b/out-of-memory-sample/src/main/java/com/microsoft/azure/spring/sample/service/HeapMemoryOut.java @@ -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 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(); + } + } +} \ No newline at end of file diff --git a/out-of-memory-sample/src/main/java/com/microsoft/azure/spring/sample/service/LongString.java b/out-of-memory-sample/src/main/java/com/microsoft/azure/spring/sample/service/LongString.java new file mode 100644 index 0000000..9638002 --- /dev/null +++ b/out-of-memory-sample/src/main/java/com/microsoft/azure/spring/sample/service/LongString.java @@ -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; + } + } +} diff --git a/out-of-memory-sample/src/main/java/com/microsoft/azure/spring/sample/service/MemoryTools.java b/out-of-memory-sample/src/main/java/com/microsoft/azure/spring/sample/service/MemoryTools.java new file mode 100644 index 0000000..0775c0a --- /dev/null +++ b/out-of-memory-sample/src/main/java/com/microsoft/azure/spring/sample/service/MemoryTools.java @@ -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 memoryPoolMXBeans = ManagementFactory.getMemoryPoolMXBeans(); + for (MemoryPoolMXBean bean : memoryPoolMXBeans) { + System.out.println(bean.getName() + ": " + bean.getUsage()); + } + List memoryManagerMXBeans = ManagementFactory.getMemoryManagerMXBeans(); + for (MemoryManagerMXBean bean : memoryManagerMXBeans) { + System.out.println(bean.getName() + ": " + Arrays.asList(bean.getMemoryPoolNames())); + } + System.out.println(); + return 0; + + } +} \ No newline at end of file diff --git a/out-of-memory-sample/src/main/resources/application.properties b/out-of-memory-sample/src/main/resources/application.properties new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/out-of-memory-sample/src/main/resources/application.properties @@ -0,0 +1 @@ +