• JVM——垃圾回收机制


    一、VisualVM工具的使用

      1、为什么使用VisualVM   

          VisualVM,能够监控线程,内存情况,查看方法的CPU时间和内存中的对 象,已被GC的
        对象,反向查看分配的堆栈(如100个String对象分别由哪几个对象分配出来的)。

      2、VisuaIVM的优点  

          VisualVM使用简单,几乎0配置,功能还是比较丰富的,几乎囊括了其它JDK自带命令的
        所有功能。

      3、如何启动VisuaIVM

        (1)在jdk的安装目录的bin目录下,找到jvisualvm.exe,双击打开即可
        

         (2)打开页面如下

        

         (3)查看本地进程

        

         (4)查看CPU、内存、类、线程运行信息

        

         (5)查看线程详情

        

    二、垃圾回收

      1、什么是垃圾回收

        程序的运行必然需要申请内存资源,无效的对象资源如果不及时处理就会一直占有内存
       资源,最终将导致内存溢出,所以对内存资源的管理是非常重要了。
        (1)C/C++语言的垃圾回收   
            在C/C++语言中,没有自动垃圾回收机制,是通过new关键字申请内存资源,通过delete
          关键字释放内存资源。
          如果,程序员在某些位置没有写delete进行释放,那么申请的对象将一直占用内存资源,
          最终可能会导致内存溢出。
        (2)Java语言的垃圾回收
            为了让程序员更专注于代码的实现,而不用过多的考虑内存释放的问题,所以,在Java语
          言中,有了自动的垃圾回收机制,也就是我们熟悉的GC。
          有了垃圾回收机制后,程序员只需要关心内存的申请即可,内存的释放由系统自动识别
          完成。
            换句话说,自动的垃圾回收的算法就会变得非常重要了,如果因为算法的不合理,导致
          内存资源一直没有释放,同样也可能会导致内存溢出的。
          当然,除了Java语言,C#、Python等语言也都有自动的垃圾回收机制。 

      2、垃圾回收的常见算法 

        (1)引用计数法

             引用计数是历史最悠久的一种算法,最早George E. Collins在1960的时候首次提出,50
           年后的今天,该算法依然被很多编程语言使用。 
           1.1.1原理:       
              假设有一个对象A,任何一个对象对A的引用,那么对象A的引用计数器+1,当引用失败
            时,对象A的引用计数器就-1,如果对象A的计数器的值为0,就说明对象A没有引用了,
            可以被回收。
           1.1.2优缺点
             优点:   
              实时性较高,无需等到内存不够的时候,才开始回收,运行时根据对象的计数器是否
              为0,就可以直接回收
              在垃圾回收过程中,应用无需挂起。如果申请内存时,内存不足,则立刻报
              outofmember 错误。
              区域性,更新对象的计数器时,只是影响到该对象,不会扫描全部对象。
             缺点: 
              每次对象被引用时,都需要去更新计数器,有一点时间开销。
              浪费CPU资源,即使内存够用,仍然在运行时进行计数器的统计。
              无法解决循环引用问题。(最大的缺点) 

        (2)什么是循环引用? 

    class TestA{
      public TestB b;
    }
    class TestB{
      public TestA a;
    }
    public class Main{
      public static void main(String[] args){
        A a = new A();
        B b = new B();
        a.b=b;
        b.a=a;
        a = null;
        b = null;
      }
    }
    虽然a和b都为null,但是由于a和b存在循环引用,这样a和b永远都不会被回收。

        (3)标记清除法  

          标记清除算法,是将垃圾回收分为2个阶段,分别是标记和清除。
          标记:从根节点开始标记引用的对象。
          清除:未被标记引用的对象就是垃圾对象,可以被清理。
          优点:
            可以看到,标记清除算法解决了引用计数算法中的循环引用的问题,没有从root节点引
            用的对象都会被回收。
            同样,标记清除算法也是有
          缺点:
            效率较低,标记和清除两个动作都需要遍历所有的对象,并且在GC时,需要停止应
            用程序,对于交互性要求比较高的应用而言这个体验是非常差的。
            通过标记清除算法清理出来的内存,碎片化较为严重,因为被回收的对象可能存在于
            内存的各个角落,所以清理出来的内存是不连贯的。 
          

        (4)标记压缩算法    

            标记压缩算法是在标记清除算法的基础之上,做了优化改进的算法。和标记清除算法一
          样,也是从根节点开始,对对象的引用进行标记,在清理阶段,并不是简单的清理未标
          记的对象,而是将存活的对象压缩到内存的一端,然后清理边界以外的垃圾,从而解决
          了碎片化的问题。 
          2.4.1原理
            
          2.4.2优缺点       
              优缺点同标记清除算法,解决了标记清除算法的碎片化的问题,同时,标记压缩算法多
            了一步,对象移动内存位置的步骤,其效率也有有一定的影响。

        (5)复制算法  

              复制算法的核心就是,将原有的内存空间一分为二,每次只用其中的一块,在垃圾回收
            时,将正在使用的对象复制到另一个内存空间中,然后将该内存空间清空,交换两个内
            存的角色,完成垃圾的回收。
              如果内存中的垃圾对象较多,需要复制的对象就较少,这种情况下适合使用该方式并且
            效率比较高,反之,则不适合。
     
  • 相关阅读:
    EMES信息化制造系统的概念
    正则表达式校验日期、时间
    c#怎么string转化成ascii码
    C#实现将一个字符串进行翻转显示的6种方法,数组的 Reverse()反转方法
    把一个十六进制的字符串(包含0x或0X)转化成对应的数值 ASCII码
    为什么0-9转化成字符是+0x30,11转化成A是+0x37?
    oracle修改数据库字段长度
    表添加字段的SQL语句写法
    在数据表中添加一个字段的SQL语句怎么写-百度
    oracle创建表增加字段sql脚本,字段说明注释
  • 原文地址:https://www.cnblogs.com/tinghao/p/12420338.html
Copyright © 2020-2023  润新知