【JVM】第五章_1 故障分析
这一章就不按照书本来讲了,这里我们重来说来两个重点。
1、故障分析(补上第二章落下的内存溢出的案例情况)
2、GC两款收集器的性能调优
一、内存溢出模拟
jvm垃圾收集其实就是关注的这两块区域,堆和非堆区。
1)heap溢出
import java.util.ArrayList;
import java.util.List;
public class HeapOverTest {
/**
* heap内存溢出
* -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/Users/liuyi/logs/
*/
static class OOMObject {
}
public static void heapOver() {
List<OOMObject> list = new ArrayList<>();
while (true) {
list.add(new OOMObject());
}
}
public static void main(String[] args) {
heapOver();
}
}
先配置一下jvm的参数:
运行之后控制台输出:
进入logs文件,发生多了一个hprof的文件。这个就是当前的线程文件。
2)metaspace内存溢出
使用cglib不存的动态加载类,直到把metaspace溢出
/**
* -XX:MetaspaceSize=32M -XX:MaxMetaspaceSize=32M
* */
public static void metaspaceOver(){
while (true) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(HeapOverTest.class);
enhancer.setUseCache(false);
enhancer.setCallback(new MethodInterceptor() {
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
return methodProxy.invokeSuper(o, objects);
}
});
enhancer.create();
}
}
3)操作数栈内存溢出
/**
* VM Args: java -Xss160k
* @param depth
*/
public static void stackOutOfMemoryError(int depth) {
depth++;
stackOutOfMemoryError(depth);
}
三、解决内存溢出问题
jmap -dump:format=b,file=./heap.hprof 进程ID
导出来之后,可以用eclipse的MAT插件进行内存分析。
也可以用jvisualVM来进行查看。
四、线上死锁问题
/**
* 死锁
*/
private Object lock1 = new Object();
private Object lock2 = new Object();
public void deadlock() {
new Thread(()->{
synchronized (lock1){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lock2){
System.out.println("获取正常1");
}
}
}).start();
new Thread(()->{
synchronized (lock2){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lock1){
System.out.println("获取正常2");
}
}
}).start();
}
public static void main(String[] args) {
new Test().deadlock();
}