JVM学习心得总结记录
1.JVM内存区域
Java虚拟机在运行时,内存分为若干区域;Java虚拟机管理的内存区域有:方法区、堆内存、虚拟机栈、本地方法栈、程序计数器。
①方法区:主要用于存储虚拟机加载的类信息、常量、静态变量、以及编译后的代码。
②堆内存:主要用于存放对象和数组,是jvm管理的内存中最大的区域。和方法区都被所有线程共享。在虚拟机启动时创建。
③程序计数器:当前线程执行字节码的行号指示器,每个线程都有一个独立的程序计数器,所以程序计数器时线程私有的一块空间。程序计数器是虚拟机规定的唯一不会发生内存溢出的区域。
④虚拟机栈:描述的是方法的内存模型,是每个线程私有的一块内存空间。每个虚拟机栈中都有若干个栈帧(存储局部变量,操作数栈,动态链接,返回地址等),一个栈帧对应代码中的一个方法,当线程执行到这个方法时,就代表这个方法对应的栈帧进入虚拟机栈并处于栈顶,一个方法从被调用到结束,就是一个栈帧从入栈到出栈的过程。
⑤本地方法栈:执行本地方法(注意:虚拟机栈执行的java方法)
2,JVM内存溢出
①堆内存溢出:堆内存主要存放对象,数组等,不断的new对象并且不会被回收,当对象所占空间超过堆内存容量时就会堆内存溢出 outofmemory;
常见堆内存溢出原因:加载数据过多,对象引用过多且使用完没有清空,代码死循环,堆内存分配不合理,网络问题等。
②虚拟机栈/本地方法栈溢出:stackoverflow 线程请求的栈的深度大于虚拟机所允许的最大深度(栈帧数量过多,线程嵌套调用的方法数量过多)时就会栈溢出,栈内存空间 = 可用物理内存 - 最大堆内存 - 最大方法区内存
假如栈占用内存512M,每个线程栈大小1M,此时虚拟机最多创建512个线程,超出时没有空间可用就会报outofmemory。
常见栈内存溢出:递归找不到出口。
③方法区溢出:方法区主要用于存储虚拟机加载的类信息、常量、静态变量、以及编译后的代码等,当没有足够的内存来存放这些数据时就就是方法区溢出。