首先给你们讲一个梗,为何Java程序员愈来愈多,而C++程序员愈来愈少呢?—— 那还不是由于不用管理内存啊程序员
在C++中,本身new的对象,在不用的时候须要手动释放。而在Java里,你能够释放你的双手,将这项工做交给JVM本身管理。在JVM里面,这种机制叫作垃圾回收(Garbage Collection)机制。
算法
ps:本文不涉及垃圾收集器,主要是讲垃圾回收的思路。cdn
Java的变量一共存储在三个地方、方法区、堆、栈对象
主要存放常量,静态常量、常量池,在程序编译的时候,这块内存就已经被分配出来了,伴随程序的一辈子。blog
是JVM管理的内存最大的一块,存放全部的实例对象,也是垃圾收集器管理的主要区域。也称为“GC堆”生命周期
当方法被执行的时候,方法内部的局部变量就会被存储在栈里,当方法执行完毕的时候,刚刚存储的局部变量会被自动释放。ip
前面说到垃圾收集器管理的是堆,在回收以前,一般须要判断这个对象是不是存活的。内存
遍历对象,当这个对象被其余对象引用的时候计数器就加1,当引用失效的时候,计数器减1。当对象的计数器为0时,则表示该对象没有被引用。这种方法效率很高,可是没法解决互相引用的问题。所以主流JVM都未采用这种方法。虚拟机
这一算法的思想是从GC Roots做为起始点,从这些节点往下搜索,搜索的路径叫作引用链,当一个对象没有任何引用链能够到GC ROOT的时候,则证实该对象是不可用的。通常想要宣告一个对象死亡,至少要经历两次标记,即标记-筛选-标记。 it
不足:
将可用内存分为两块,每次只使用其中的一块。一块内存使用完的时候,将存活下来的对象复制到另外一块中,再清除这一块内存。这样就没什么内存碎片可言了。
效率高,解决了内存碎片的问题。
复制-收集算法,在对象存活率高的状况下,要进行屡次复制,效率比较低。因此说为此提出了“标记-整理”算法。
标记过程同上,而后让全部存活的对象移动到另外一端,而后清理掉边界外的内存。
分代收集算法比较常见,通常把堆分为新生代和老年代,这样能够根据各个年代的特色采用适当的算法。
在JDK1.2以后,Java对引用的概念进行了扩充,将引用分为强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)、虚引用(Phantom Reference)四种,这四种引用强度依次逐渐减弱。
就是指在程序代码之中广泛存在的,例如new出来的对象,只要强引用还在,该对象就不会被回收。
用来描述一些还有用但并不是必须的对象。在内存即将溢出以前,垃圾收集器会将这些对象进行回收。
用户描述非必须对象的。不管当前内存是否足够,随时都有可能被回收。
虚引用不会影响该对象都生命周期,只会在该对象被回收的适合得到一个系统通知。