- 文章开篇问一个问题吧,一个java程序,如果其中一个线程发生了OOM,那进程中的其他线程还能运行吗?
接下来做实验,看看JVM的六种OOM之后程序还能不能访问。在这里我用的是一个springboot程序。
/**
* @author :charon
* @date :Created in 2021/5/17 8:30
* @description : 程序启动类
* @version: 1.0
*/
@SpringBootApplication
public class CharonApplication {
public static void main(String[] args) {
SpringApplication.run(CharonApplication.class, args);
}
}
- 监测服务是否可用(http://localhost:8080/checkHealth 测试服务正常可用):
/**
* @author :charon
* @date :Created in 2021/5/17 8:49
* @description : 测试服务是否可用
* @version: 1.0
*/
@RestController
public class CheckHealthController {
@RequestMapping("/checkHealth")
public String stackOverFlowError(){
System.out.println("调用服务监测接口-----------------------");
return "服务监测接口返回";
}
}
1.StackOverflowError(栈溢出)
- 栈溢出代表的是:当栈的深度超过虚拟机分配给线程的栈大小时就会出现error。
/**
* @author :charon
* @date :Created in 2021/5/17 8:49
* @description : 测试java.lang.StackOverflowError: null的错误
* @version: 1.0
*/
@RestController
public class StackOverFlowErrorController {
/**
* 递归调用一个方法,使其超过栈的最大深度
*/
@RequestMapping("/stackOverFlowError")
public void stackOverFlowError(){
stackOverFlowError();
}
}
-
使用浏览器调用栈溢出的接口(localhost:8080/stackOverFlowError),发现后台报了栈溢出的错误。
-
调用监测程序可用的接口,发现还是可以正常访问。
2.Java heap space(堆内存溢出)
-
当GC多次的时候新生代和老生代的堆内存几乎用满了,频繁触发Full GC (Ergonomics) ,直到没有内存空间给新生对象了。所以JVM抛出了内存溢出错误!进而导致程序崩溃。
-
设置虚拟机参数(-Xms10m -Xmx10m -XX:+PrintGCDetails),如果不设置的话,可能会执行很久。
@RestController
public class JavaHeapSpaceController {
/**
* 使用是循环创建对象,是堆内存溢出
*/
@RequestMapping