堆、OOM内存溢出、GC(垃圾回收)

1.堆

在这里插入图片描述

GC垃圾回收,主要是在伊甸园区和养老区,没有被回收的存放在幸存区;

假设内存满了,OOM,堆内存不够!会报错

新生区:

类:诞生和成长的地方,甚至死亡;

伊甸园区:所有的对象都是在伊甸园区new出来的;

幸存区(0,1):轻GC回收之后剩下的会进入幸存区。

养老区:

新生区内存占完了,存入养老区

永久区:

元空间:逻辑上存在,物理上不存在;

这个区域常驻内存,用来存放JDK自身携带的Class对象,interface元数据,存储的是java运行时的一些环境或类信息,这个区域不存在垃圾回收。(关闭VM虚拟机就会释放这个区域的内存)

jdk1.6之前:永久代,常量池在方法区中;

jdk1.7:永久代,慢慢退化了,常量池在堆中;

jdk1.8之后:无永久代,常量池在元空间中。

2.OOM

一个启动类,加载了大量的第三方jar包,Tomcat部署了太多的应用,大量动态生成的放射类,不断被加载,直到内存满,就会出现OOM。

1.尝试扩大堆内存,看结果(VM:-Xms1024m -Xmx1024m -XX:+PrintGCDetails)

2.分析内存,看一下哪个地方出了问题(内存快照工具Jprofiler:能够看到代码第几行出错)

Jprofiler作用:

  • 分析Dump内存文件,快速定位内存泄露;
  • 获得堆中的数据
  • 获得大的对象
//-Xms 设置初始化内存分配大小,默认1/64
//-Xmx 设置最大分配内存,默认1/4
//-XX:+PrintGCDetails  打印垃圾回收信息
//-XX:HeapDumpOnOutOfMemoryError //oom Dump检查内存问题

3.GC(垃圾回收)

JVM再进行GC时,并不是对这三个区域统一回收,大部分时候回收的是新生代~

  • 新生代
  • 幸存区(from,to)会交换,谁空谁是to
  • 老年区:当一个对象经历了15次GC,还没有死,就会进入老年区

GC两种类:轻GC(普通的GC),重GC(全局的GC)

GC的算法:

(1)引用计数法:引用计数法通过在对象头分配一个字段,用来存储该对象引用计数。一旦该对象被其他对象引用,计数加 1。如果这个引用失效,计数减 1。当引用计数值为 0 时,代表这个对象已不再被引用,可以被回收。

(2)复制算法:作用在新生代,每次GC都会将Eden中活的对象移到幸存区中:一旦Eden区被GC后,就会是空的!

  • 优点:没有内存碎片

  • 缺点:浪费了内存空间,多了一半空间永远是空to

最佳适用场景:对象存活度较低的情况!

(3)标记清除法:

在这里插入图片描述

  • 优点:不需要额外的空间

  • 缺点:两次扫描,严重浪费时间,会产生内存碎片

(4)标记压缩:在标记清除的基础上增加一个压缩的过程,再次扫描,多一个移动成本,将存活的对象排个序。

总结:

内存效率:复制算法>标记清除算法>标记压缩算法(时间复杂度)

内存整齐度:复制算法=标记压缩算法>标记清除算法

内存利用率:标记清除算法=标记压缩算法>复制算法

注:没有最好的算法,只有最合适的算法!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值