zoukankan      html  css  js  c++  java
  • java内功 ---- jvm虚拟机原理总结,侧重于GC

    参考资料:《深入理解java虚拟机》、《thinking in java》、《Effective Java》

    直接从最要紧的地方讲,Java GC算法。需说明一点,GC机制只是涉及堆内存的。因为堆内存是动态的,在程序运行期间分配的。

    一.判断什么需要被回收:

    1.引用计数法

               问题在于两个对象互相引用,然后各种指向null。堆内存中的对象是不会被回收的。

           上图是体现一种变化,绘画技巧不行,用绿框表示对象成员,两个对象互相指向。

           依据引用计数法,当a=null,b=null。A、B不会被回收内存,因为他们互相引用。

    2,可达性分析算法

           为了解决引用计数的缺陷,引入可达性分析算法。

           GC Root:

                  1,虚拟机栈(栈帧中的本地变量表)中引用的对象。

                  2,方法区中类静态属性引用的对象。

                  3,方法区中常量引用的对象。

                  4,本地方法栈中JNI(即一般说的Native方法)引用的对象。

            对于之前的例子。当a、b(栈中的变量)指向A、B(堆中的变量)时 ,A与B是GC Root。当a=null、b=null。A与B不再是GC Root,虽然A与B相互引用,但没有与其它任何GC Root可达。所以A与B,会被回收。

    3.方法区的回收

            永久代的垃圾收集主要回收两部分内容:废弃常量和无用的类。废弃常量的回收与对象的回收是一个道理。

             重点谈废弃的类需满足的几点:

                     1,该类的所有实例都已被回收

                     2,加载该类的ClassLoader已经被回收

                     3,该类对应的java.lang.Class对象没有在任何地方被引用,无法在任何地方通过反射访问到该方法

    二,垃圾收集算法:

    1.标记-清除

             分为,标记和清楚两个阶段,想想便知道,会留下很多内存碎片。

    2.复制算法

              将内存分为8:1:1。8的部分为Eden,1的部分为Survivor。

              首先是使用Eden部分内存,按照1的标记-清除算法来,做垃圾收集,自然会产生碎片。当Eden部分内存不够时,就将活着的对象都放入一个Survivor。此时Eden为空。继续分配对象内存、同时也就继续回收。这时那个装载着存活对象的survivor也在做着垃圾回收。当Eden或这个survivor内存不够用的时候,便将二者内存里活着的对象都放入另一个surviror。如此循环往复。

    3.标记-整理

               与标记-清除相对,是一种标记后不直接清除,而是将所有活着的对象像一端移动,然后直接清理掉端边界以外的内存。

               不同场合应当使用不同的垃圾回收算法,当前商业虚拟机的垃圾回收都采用“分代收集”算法。新生代死亡率高,采用复制算法,老年代存活率高,采用标记-清除或者标记-整理。

     

    三,实用性建议

            最后我们看下《Effective Java》一书给出的实用性建议:

                     1.消除过期的对象引用

                           了解了上述判断对象是否该回收的内容后,你就知道,如果堆内存里的对象被栈内存的变量所引用时,这块对象内存是不会被回收的。这便是java的内存泄漏。其逻辑在于,虽然Java的GC很有效,但一个应当释放的堆一直被你引用着,GC程序是没法给它判死刑的。

                     2.避免使用终结方法

                           终结方法(finalizer)通常是不可预测的,也是很危险的,一般情况下是不必要的。使用终结方法会导致行为不稳定,降低性能,以及可移植性问题。

                     这两点结合起来看,就是java不像C++有好用的delete方法来释放对象内存,java需要依赖GC,但是java要保证及时释放引用,以保证不会内存泄漏。

     
     
  • 相关阅读:
    每天一个小算法(Heapsort)
    每天一个小算法(matlab armijo)
    每天一个小算法(Shell sort5)
    每天一个小算法(Shell Sort3)
    每天一个小算法(Shell Sort2)
    Java并发编程:阻塞队列
    Java并发编程:并发容器之CopyOnWriteArrayList
    Java并发编程:并发容器之ConcurrentHashMap
    Java并发编程:CountDownLatch、CyclicBarrier和Semaphore
    豆瓣的前世今生
  • 原文地址:https://www.cnblogs.com/rixiang/p/5801214.html
Copyright © 2011-2022 走看看