去参加了一次5天的windows kernal dump培训,虽然从技术上看收获不大,但是在其中对我分析问题尤其是从jvm的角度看问题起到了蛮大的启发作用,写一个自己的重新认知。
想到以前被有的同学批判了一下实战太少,所以还是要自己撸代码看。
内存溢出,是一个老生常谈的问题,但是大部分的程序员遇到较少,这就要归功于jvm同学了,尤其是回收机制的更新的真的快。
内存溢出显示到外部肯定是有一个表象。对于错误异常日志来说,会分为几类
1.堆溢出
java.lang.OutOfMemoryError: GC overhead limit exceeded(有其他种类,直接查文档)
JVM在启动的时候会自动设置JVM Heap的值, 可以利用JVM提供的-Xmn -Xms -Xmx等选项可进行设置。Heap的大小是Young Generation 和Tenured Generaion 之和。在JVM中如果98%的时间是用于GC,且可用的Heap size 不足2%的时候将抛出此异常信息。
2.非堆/Metaspace溢出(jdk1.7以前是方法区,原谅我不想再ps图片,自动脑补替换一下,替换原因可以看看https://www.cnblogs.com/duanxz/p/3726574.html 这篇文章,分析的很好)
java.lang.OutOfMemoryError: Metaspace
3.栈溢出
java.lang.StackOverflowError
JVM依然是采用栈式的虚拟机,这个和C和Pascal都是一样的。函数的调用过程都体现在堆栈和退栈上了
所以可能以下2种可能
单个线程请求的栈深度大于虚拟机所允许的最大深度
创建的线程过多
以下就是几种溢出常见的代码
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.6</version>
</dependency>
--vm options
-Xms16m -Xmx32m -XX:MetaspaceSize=10M -XX:MaxMetaspaceSize=10M -verbose:gc -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=F:\
import java.util.*;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class JvmTest {
public static void main(String[] args) throws Exception {
JvmTest jmTest = new JvmTest();
//jmTest.statOverFlowThreadCountTest();//statck 线程多溢出
//jmTest.stactOverFlowTest();//statck 深度导致溢出
jmTest.outOfMemoryTest();//out memory
//jmTest.mateSpaceTest();//mateSpa