了解JVM工作机制和垃圾回收机制

文章目录

1 JVM

JVM 是一个程序,运行起来对于操作系统来说只是一个普通进程,
对于Java程序来说就是整个世界(硬件,OS)

1.1 JVM 的定位:
我们平时运行程序时,就是根据Path 找到JRE下的 java.exe 就是JVM程序

JVM运行起来之后的工作:
从硬盘上加载,识别,解析,存储类文件,并且可以正确运行这些文件,并进行代码执行过程中的内存管理。
1)进行类的加载
2)类的存储,内存分区
3)执行代码
4)内存管理

JVM运行时的内存划分:
1.PC 程序计数器区
2.栈区
3.堆区
4.方法区
5.常量池

2 GC

GC包括:
1)垃圾回收
2)垃圾回收器

GC的职责:
进行内存的分配和内存的回收

垃圾回收的是对象代表的内存空间
垃圾回收的步骤:
1)标记 判断哪些内存可以被回收
2)清除 释放空间并整理 方便之后申请空间更容易

PC 和 栈 是和线程同生共死的,只要线程在,就不能回收;只要线程不在,就必须回收,由JVM直接管理;
方法区 和 常量池 是和类绑定在一起的,在类被加载到内存之后,很少失去作用。
由于以上两点,那么垃圾回收的主要是对象占据的堆内存了。
垃圾回收是以对象为单位进行的。

判断对象已死的方法有两种:
1)引用计数法
每个对象除了带有属性之外,还带有管理数据,用来显示这个对象的引用数
这个管理数据只对JVM可见,对Java普通程序不可见,当该对象的引用数rc为0时,代表对象已死。
缺点:当两个对象的引用的属性分别引用对方对象时,rc永远无法为0

2)可达性分析法
像类中静态属性引用指向的对象,因为类一直在,就一直活着,线程里的调用栈的栈帧中的引用指向的对象,因为线程活着,也活着,
这些引用/对象叫做GC Roots,在GC进行可达性分析时,从所有的GC Roots出发可以到达的对象必须活着,没有到达的对象可以死了。

 之前一直以为引用都存在栈区,然而这种想法是大错特错的。要看变量的形态
 变量的类型有:基本类型,引用类型
 变量的形态有:局部变量,形参变量,成员变量(属性),静态变量
 如果该引用是局部变量就保存在栈区,如果是静态变量保存在方法区,如果是成员变量保存在堆区
 基本数据类型的变量直接保存的是数据,而引用数据类型的变量保存的是对象的地址,通过地址找到对象,进而操作对象得出数据。

但是,如果在GC的过程中,可达性分析期间对象的引用关系发生了变化,会造成致命错误。该回收的没有回收,不该回收的却回收了。
所以通常垃圾回收器会在垃圾回收时,停止应用线程的执行。

通过引用可以找到对象,引用也决定了对象的生死,但是有时并不希望引用决定对象的生死,可以分离引用的类型

引用的类型:
1)强引用: 被引用的对象必需活着
2)软引用: 被引用的对象尽可能活着,在内存紧张时可以回收
3)弱引用: 被引用的对象,每次GC就会被收回
4)虚引用: 对象的生死和引用无关,但是对象被回收时可以收到通知

如何清除对象?

方法一:清除+整理 每次释放内存都进行整理,如果只清除不整理会导致内存碎片化,即使有空间,也没法用了
缺点:耗时
方法二:复制 清理时,将活着的对象复制到特定的位置,然后回收剩下的垃圾 适合于大部分都是垃圾的情况
缺点:存在内存空置状态

绝大部分的对象生命周期很短,每次GC都被回收
没在被GC回收的对象随着生命的越来越长,越不容易死去。

对象的管理数据里有一个年龄,每活过一次GC年龄涨一岁
新生代
对象刚创建时在伊甸区,有1%的概率活过生命中的第一次GC,进入生长区
经历生命中的第二次GC有3%的概率活下去,
经历生命中的第n次GC,仍然活下去,年龄到达了一定阈值,进入
老年代
这时候如果GC适合使用清除+整理的方法。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值