JVM——》内存泄露案例

本案例,是由ThreadLocal引起的内存泄露,最终导致内存溢出

模拟堆内存溢出
-Xms1000M -Xmx1000M
堆内存溢出时自动导出堆文件
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=jvm.hprof

一、代码

1、TestApplication.java

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

/**
 * 启动前请设置参数:
 * 	-Xms1000M -Xmx1000M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=jvm.hprof
 */
@SpringBootApplication
public class TestApplication {

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

2、TLController.java

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;

@RestController
public class TLController {
    @RequestMapping(value = "/tl")
    public String tl(HttpServletRequest request) {
        ThreadLocal<Byte[]> tl = new ThreadLocal<Byte[]>();
        // 1MB
        tl.set(new Byte[1024 * 1024]);
        return "ok";
    }
}

二、启动

1、 idea启动

模拟堆内存溢出
-Xms1000M -Xmx1000M
堆内存溢出时自动导出堆文件
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=jvm.hprof

JVM——》内存泄露案例_第1张图片

2、 jar启动

java -jar -Xms1000M -Xmx1000M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=jvm.hprof jvm-case-0.0.1-SNAPSHOT.jar

三、正常访问

http://127.0.0.1:8080/tl
JVM——》内存泄露案例_第2张图片

四、模拟并发 (工具:jmeter,1000并发)

1、找到jmeter目录,运行 jmeter.bat文件JVM——》内存泄露案例_第3张图片

JVM——》内存泄露案例_第4张图片

2、添加线程组,配置线程数

JVM——》内存泄露案例_第5张图片
JVM——》内存泄露案例_第6张图片

3、添加Request

JVM——》内存泄露案例_第7张图片

JVM——》内存泄露案例_第8张图片
JVM——》内存泄露案例_第9张图片

4、运行jmeter

JVM——》内存泄露案例_第10张图片

五、分析结果

1、分析日志

JVM——》内存泄露案例_第11张图片

2、jstack分析

语法 :
    jstack PID			查看线程情况,发现没有死锁或者IO阻塞的情况
示例:
    jstack 50700

JVM——》内存泄露案例_第12张图片

3、jmap分析

语法:
    jmap -heap PID			查看堆内存的使用
示例:
    java -heap 50700		发现堆内存的使用率已经高达99.93%  

JVM——》内存泄露案例_第13张图片

语法:
    jmap -histo:live PID | more			查询哪个实例对象占用内存最多
示例:
    jmap -histo:live 50700 | more

JVM——》内存泄露案例_第14张图片

你可能感兴趣的:(JVM,开发工具,jvm,内存,泄露,溢出,并发)