JVM原理、架构—垃圾回收机制

搞java的都知道在编写java程序的时候不需要要考虑资源的释放,因为JVM会自动将不是用的对象GC掉。这里自动是个什么原因呢?就是程序员不能对垃圾进行回收,垃圾回收并不会及时清理内存,即便有时候程序需要需要的额外内存,垃圾回收不会随时发生。所以如果想写出高校的程序,需要根据垃圾回收的原则,合理的分配内存。

为什么要进行垃圾回收?

随着程序的运行,对象、变量占据的内存不断增多,如果不及时的回收这些内存资源,程序的性能会不断的下降,甚至会使系统出现一些问题;

哪里垃圾需要进行回收?

我们知道堆是用来存放对象的地方,这个地方是垃圾回收的重要地方,还有就是方法区,方法区中有着许多变量。为什么JVM栈、本地方法栈、PC计数器不用垃圾回收?因为这些的生命周期是与线程同步的,随着线程的销毁这些内存也会自动释放。

什么时候进行垃圾回收?

有一种算法是计数器算法,为每个对象添加一个计数器,当引用一次计数器加1,失去引用计数器减1。当计数器为0的时候则可以进行回收了。但是这种算法有明显的错误,如当两个对象互相引用但是却都没有用的时候,他们已经没有用了,但是又不符合垃圾回收的规则,所以JVM并没有使用这种策略。而是采用一种根搜索的算法。

他的基本思想就是:从一个叫做GC Roots的对象开始向下进行搜索,如果一个对象不能够到达这个GC Roots,也就是失去引用了,就可以进行回收了(考虑也有finalize()方法的对象)。如上图的o5,o6,o7即便互相引用呢,但是无法到达GC Roots对象,所以可以进行垃圾回收了。

引用是什么?

引用分为强引用、软引用、弱引用、虚引用四中。

强引用:就是刚刚创建的对象所加的引用,他不会被GC

软引用:是可被回收的,如果内存不紧张,则不会被GC,如果内存紧张则就会被回收。为什么可以被回收却不回收呢?比如内存缓冲区中,一个对象只是暂时没有被引用,下次引用的时候如果缓冲区中有这个引用则就直接使用,如果没有这个引用就会创建,所以他是可以被回收的。

弱引用:就是一定要被GC的,不管内存是否紧张,在GC的时候,只要这个对象被标记为弱引用,则就会被GC

虚引用:就是可以被忽略不计的,他的作用只是进行一些跟踪记录,辅助finalize()函数使用。

什么样的类需要被回收?

该类的所有实例都已经被回收了

加载该来的ClassLoader已经被回收了

该类对应的反射类对象没有被任何地方使用

如何进行垃圾回收?

由上面回收哪里的垃圾,可以知道垃圾回收针对的是新生代、旧生代、持久代。不同代有着不同的GC算法。对于新生代适合那些声明周期较短、频繁创建和销毁的对象;旧生代适合与声明周期较长的对象;持久代主要适合一些常量,默认信息等。

常见算法:

标记-清除算法(mark-sweep)

最基础的GC算法,就是将要回收的对象标记,之后扫描的时候对标记的对象,进行回收。这样就会需要产生标记和删除两个步骤,所以效率不高,而且还会产生碎片,如果大对象需要使用连续的内存空间,则还需要清理碎片。

复制算法(copying)

我们知道新生代有三个区域Eden和两个Survivor,JVM会将二者比例协调为8:1,在Survivor中有一块空闲的区域。当进行垃圾回收的时候将不需要GC的对象放到这块空闲区域,然后将Eden和Survivor这两个区域进行完全清理。这样可以会有一个问题,就是如果这块空闲的区域不够大,怎么办。这时候就需要借助持久代的区域了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值