目前默认的虚拟机是HotSpot(TM)虚拟机
首先是类加载器加载编译之后的.class文件,将文件加载的JVM
线程共享的区域:方法区、堆
每个线程都独有的一份区域:虚拟机栈、本地方法栈、程序计数器
方法区:类中的信息,常量,生命周期是类级别(jvm运行起来之后一直存在)
堆:分配内存,放对象(new出来的对象都放在这里)。某个对象在后续没有程序使用,就需要被回收。自动回收(GC)。
程序计数器:记录class字节码执行到哪里了,下一步该执行什么。
虚拟机栈:存放方法的局部变量,遇到方法之后就会进行压栈 弹栈,方法执行结束之后弹栈,局部变量挂掉
本地方法栈:调用源码方法c++
堆栈溢出例子:
jvm参数配置
-Xms20m
-Xmx20m
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/a.dump
代码:
public class Main {
public static void main(String[] args) {
/**
* 这个是用来测试栈溢出
*/
fac(50000);
/**
* 这个是用来测试堆溢出
* 这里先new了一个list然后在无限循环是因为,在这个list引用中无限添加,程序会一直占用这个引用,不会释放,会一直存在于堆中
*/
List<String> list = new ArrayList<>();
while (true){
list.add("true");
}
}
public static long fac(int n){
if (n == 0){
return 1;
}
System.out.println(n);
return fac(n-1);
}
}
分析堆内存溢出工具:jhat(jdk自带的一个工具) Eclipse Memory Analyzer