zoukankan      html  css  js  c++  java
  • Java内存泄露的原因

    Java内存泄露的原因

    1、静态集合类像HashMap、Vector等的使用最容易出现内存泄露,这些静态变量的生命周期和应用程序一致,所有的对象Object也不能被释放,因为他们也将一直被Vector等应用着。

        这种情况可以通过remove clear方式释放对象,没有问题。

    2、数据库的连接没有关闭情况,包括连接池方法连接数据库,如果没有关闭ResultSet等也都可能出现内存泄露的问题。

        这是代码中经常出现的问题。

    3、内部类和外部类的引用容易出现内存泄露的问题;监听器的使用,java中往往会使用到监听器,在释放对象的同时没有相应删除监听器的时候也可能导致内存泄露。

        我认为此说法是不准确, 及时将对象设置为null可以加快内存回收,但并不代表内存不可达或者泄露,我们使用一个例子来验证下

        

    package testawt;
    
    import java.io.Console;
    import java.util.Scanner;
    import java.util.Vector;
    
    class person
    {
        public String name;
        public String age;
        private hand  handhello;
        public person ()
        {
            handhello=new hand(this);
        }
        public void sayhello()
        {
            handhello.Shake();
        }
        public void finalize()
         {
             System.out.println("gc person!");
         }
    }
    class hand
    {
        private person per;
        public hand(person per)
        {
            this.per=per;
        }
        public void Shake()
        {
            System.out.println("Shake!");
        }
        public void finalize()
         {
             System.out.println("gc hand!");
         }
    }
    
    public class testm {
    
        private static Scanner in;
        public static void main(String[] args) 
        {
            Vector<person> v = new Vector<person>();  
            for (int i = 1; i<20; i++)
            {
                person o = new person();
                v.add(o);
            }
            v.clear();
            System.gc(); 
            //所有对象释放了
            in = new Scanner(System.in);  
            int a = in.nextInt(); 
            for (int i = 0; i < 10; i++)   System.out.println(a+i);
        }
    
    }

        person和hand存在相互引用。但是强制调用gc ,能够回收内存。
    gc person!
    gc hand!
    gc person!
    gc hand!
    gc person!

    3、大量临时变量的使用,没有及时将对象设置为null也可能导致内存的泄露

        我认为此说法不准确,及时将对象设置为null可以加快内存回收,但并不代表内存不可达或者泄露,如果你觉得自己使用了大量的临时变量,可以自己强制执行一次System.gc();

       

    import java.io.Console;
    import java.util.Scanner;
    import java.util.Vector;
    
    class person
    {
        public String name;
        public String age;
        public hand  handhello;
        public void finalize()
         {
    
             System.out.println("gc person!");
         }
    
    }
    class hand
    {
        public void hello()
        {
            System.out.println("hello!");
        }
        public void finalize()
         {
             System.out.println("gc hand!");
         }
    }
    
    class footer
    {
        public void walk()
        {
            System.out.println("walk!");
        }
        public void finalize()
         {
             System.out.println("gc footer !");
         }
    }
    
    public class testmain {
    
        private static Scanner in;
    
        public static void main(String[] args) 
        {
            // TODO Auto-generated method stub
            Vector<person> v = new Vector<person>();
            
            for (int i = 1; i<20; i++)
            {
                person o = new person();
                o.handhello=new hand();
                v.add(o);
                
                footer f=new footer();
                f.walk();
                //o = null; 
            }
            v.clear();
            System.gc(); 
            //所有对象释放了
            in = new Scanner(System.in);  
            int a = in.nextInt(); 
            for (int i = 0; i < 10; i++)   System.out.println(a+i);
        }
    
    }

      运行结果

    gc footer !
    gc hand!
    gc person!
    gc footer !
    gc hand!
    gc person!

  • 相关阅读:
    OOAD-2 UML建模、类、接口、类图的详细介绍
    OOAD-1 GOF中的23种设计模式的分类和功能
    java核心技术第四章疑问点
    数据结构中的遇到的一些小知识整理
    springboot中一次坑爹的打包体验
    mybatis中@param的使用与否
    mybatis 防止sql注入
    java窗口
    java异常处理
    第三次上级作业
  • 原文地址:https://www.cnblogs.com/dragonsuc/p/4337349.html
Copyright © 2011-2022 走看看