Jvm内存模型以及GC回收机制

前言:作为一个合格Java程序员 ,我觉得对于JVM了解是很有必要。对于代码中常见的内存点以及GC回收策略了解更是很有必要。这是写出高质量程序的基准;
先卖一个关子吧:
观察下列代码 并尝试解释抛内存溢出异常的原因:

public void Test(){
List<User> userInfo = new ArrayList<User>();
	while(true){
	    User user = new User();
	    user.setUserName("xiaojun");
		userInfo.add(user);
	}
}

一 JAVA类实际运行时机在JVM中的存贮位置:
(1)PC寄存器(导航)
每个线程都有一个PC寄存器,在线程创建的时候就会进行创建。
他总是指向自己下一条地址的指令。
(2)方法区(通常指的就是静态数据)
类的基本信息(类的基本信息描述)
字段、方法信息
方法的字节码
类的基本信息
(3)堆
线程共享。
通常我们通过new的形式进行创建的对象都会保存在堆之中。
垃圾回收重点区域(新生代 老年代 后续进行介绍)
(4)栈
线程私有保证线程的安全性。
栈之中进行保存栈帧。其中方法的开始和结束对应着入栈和出栈。
栈帧之中保存的是局部变量表。(其中java中的引用就是存贮在栈帧里面的)

GC回收算法解析:
基本思路就是 找到回收对象 回收对象,释放内存。

标记过程有两种:
(1)引用标记算法 进行引用标记需要释放内存 ,完后定期进行GC回收。
(2)可达性分析算法
从根对象开始进行查找引用的链,如果能找到根对象到目标对象的引用的链,那么这个对象就不会被GC,否则就会进行触发GC完成回收的操作。
根对象:
1 局部变量量表之中的对象
2 静态常量应用的对象
3 常量应用的对象
回收过程:
(1)标记复制算法:
基本思路就是在系统内存中进行开辟两块内存结构,完后将没有标记的复制到另一块内存空间之中,完后被标记的内存空间进行整体GC。
特点:高效 但是需要的内存空间大
(2)标记压缩算法:
1 将存活的对象进行压缩到内存的另一边。
2 然后将接下来要进行GC的对象整体放到另一边。整体进行GC
(3)分代回收算法:
新生代:
新生代分为两部分,E区和S区;
新生代里面的对象几乎都是短命对象存活时间不会太久;
采用的是标记-复制算法进行处理;

	老年代:
	老年代采用的是 标记-压缩算法;
	原因是老年代中有大量的存活比较久的对象;
  1. JAVA对象的生命周期: (1)经过初始化之后进行创建对象。在堆之中进行分配内存。 (2)由于堆是分代的所以一般存储在新生代的E区中。
    (3)如果有新生代的对象进行创建的时候,放入新生代的时候发现内存不足的时候会进行一次GC;
    (4)通过可达性算法进行分析之后,找出本次要进行GC的对象,然后进行直接GC。
    (5)新生代的对象是有生命周期的。没经过一次GC之后年龄进行+1,当超过一定数值之后进行晋升。默认配置的数值是15。
    (6)如果首次创建的对象是大对象的操作,则直接进入老年代。
    (7)同理在晋升老年代的同时,也会进行内存容量判断,如果内存容量不足则进行GC。所有操作完毕之后发现内存依然不足
    就直接进行跑出异常OOM

分配担保问题解析:
简单理解就是 就是当新生代进行GC的时候,会进行判断老年代的持续空间是否大于等于新生代对象容量的总和。如果大于直接进行GC,否则老年代会进行FullGC操作,FullGC会让JVM出现卡顿的现象。

后续待更新。。。。欢迎下方留言补充

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值