持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第17天
1、栈
图 为什么main()先执行,最后结束~
====
栈:先进后出 桶:后进先出
队列:先进先出( FIFO : First Input First Output )
栈:栈内存,主管程序的运行,生命周期和线程同步;
线程结束,栈内存也就是释放,对于栈来说,不存在垃圾回收问题
一旦线程结束,栈就Over!
栈内存中:
8大基本类型+对象引用+实例的方法
栈运行原理:栈帧
栈满了: StackOverflowError
图 栈的位置示意图
图 栈帧图解 栈底部子帧指向上一个栈的方法 上一个栈的父帧指向栈底部方法
2、三种JVM
HotSpot 使用最多
JRockit BEA
J9 vm IBM
3、堆
Heap, 一个JVM 只有一个堆内存,堆内存的大小可以调节的。
类加载器读取了类文件后,一般会把什么东西放在对里面? 类的具体实例,
堆内存划分:
1)新生区 :Eden、S0、S1。对象在这里诞生、成长、甚至死亡
Eden:所有对象都是在eden区new出来的。
2)老年区
3)永久区:jdk1.8以后,叫元空间(方法区在这里,常量池在方法区里)。这个区域是常驻内存的,用来存放jdk自身携带的class对象。
GC垃圾回收,主要在伊甸园区和养老区~ 假设内存满了,OOM, 堆内存不够!
新生区
- 类: 诞生 和成长的地方,甚至死亡;
- 伊甸园区: 所有的对象都在 伊甸园区 new出来的!
- 幸存者区(0.1)
老生区
真理:经过研究,70%-99%的对象都是临时对象!|
永久区
这个区域常驻内存的,用来存放JDK自身携带的Class对象,interface元数据,存储的是java运行的一些环境类信息,这个区域不存在垃圾回收!关闭VM虚拟就会释放这个区域的内存!
一个启动类,加载了大量的第三方jar包,tomcat部署了太多的应用,大量生成反射类,不断的被类加载,直到内存满,就会出现OOM;
- jdk1.6之前: 永久代,常量池在方法区;
- jkd1.7 : 永久代,但是慢慢的退化了,去永久带,常量池在堆中;
- jdk1.8以后:无永久代,常量池在元空间
元空间:逻辑上存在,物理实际上不存在
在一个项目中,突然出现了OOM的故障,那么该如何排除
-
能够看到代码第几行出错:内存快照分析工具,MAT, Jprofiler
-
Debug,一行一行分析代码!
-
MAT,Jprofiler作用:
1.分析Dump内存文件,快速定位内存泄漏
2.获得堆中的数据
3.获得大的对象
遇到OOM问题怎么解决的?
-
尝试扩大堆内存查看结果
-Xms1024m -Xmx1024m -XX:+PrintGDetails -
分析内存,看一下那个地方出现了问题