怎么样写出带Bug的代码

1、创建class时不没有重写hashCode()equals()方法,轻则创建的对象比较时无法区分,重则将大量对象存储至map时导致内存泄漏。

  解决方法:根据业务需要重写equals()方法和hashCode()方法。

2、内部类引用外部类

2.1、非静态的内部类默认会持有外部类,尽管代码上不再使用外部类,所以如果有地方引用了这个非静态内部类,会导致外部类也被引用,垃圾回收时无法回收这个外部类。

举例

复制代码
public class Outer{
    private byte[] bytes = new byte[1024]; //外部类持有数据
    private  String name  = "Bug";
     class Inner{
        private String name;
        public Inner() {
            this.name = Outer.this.name;
        }
    }
    public static void main(String[] args) throws IOException, InterruptedException {
        int count = 0;
        ArrayList<Inner> inners = new ArrayList<>();
        while (true){
            if(count++ % 100 == 0){
                Thread.sleep(10);
            }
            inners.add(new Outer().new Inner());
        }
    }
}
复制代码

解决方法:使用静态内部类

复制代码
public class FixOuter {
    private byte[] bytes = new byte[1024 * 1024]; //外部类持有数据
    private static String name  = "Bug";
    static class Inner{
        private String name;
        public Inner() {
            this.name = FixOuter.name;
        }
    }
    public static void main(String[] args) throws IOException, InterruptedException {
        int count = 0;
        ArrayList<Inner> inners = new ArrayList<>();
        while (true){
            if(count++ % 100 == 0){
                Thread.sleep(10);
            }
            inners.add(new Inner());
        }
    }
}
复制代码

 

2.2、匿名内部类对象如果在非静态方法中被创建,会持有调用者对象,垃圾回收时无法回收调用者。

举例

复制代码
public class Outer {
    private byte[] bytes = new byte[1024];
    public List<String> newList() {
        List<String> list = new ArrayList<String>() {{
            add("1");
            add("2");
        }};
        return list;
    }
    public static void main(String[] args) throws IOException {
        int count = 0;
        ArrayList<Object> objects = new ArrayList<>();
        while (true){
            System.out.println(++count);
            objects.add(new Outer().newList());
        }
    }
}
复制代码

 

解决方法:使用静态方法

复制代码
public class FixOuter {
    private byte[] bytes = new byte[1024];
    public static List<String> newList() {
        List<String> list = new ArrayList<String>() {{
            add("1");
            add("2");
        }};
        return list;
    }
    public static void main(String[] args) throws IOException {
        int count = 0;
        ArrayList<Object> objects = new ArrayList<>();
        while (true){
            System.out.println(++count);
            objects.add(newList());
        }
    }
}
复制代码

3、ThreadLocal使用不当

3.1ThreadLocal变量会与线程绑定,如果线程长时间存在(例如线程池中的线程),而ThreadLocal变量没有被及时移除,可能会导致内存泄漏。

解决方法在使用完ThreadLocal变量后,调用remove()方法移除变量。

3.2ThreadLocal本身是线程安全的,但需要注意在使用ThreadLocal变量时,不要在多个线程中共享同一个ThreadLocal实例。

解决方法每个线程使用自己的ThreadLocal实例,或者使用InheritableThreadLocal来实现线程间的数据传递

4、IO或者网络资源没有正确关闭

解决方案:在finally块中关闭不再使用的资源;从 Java 7 开始,使用try-with-resources语法可以用于自动关闭资源

posted @   干瘪咸鱼  阅读(11)  评论(0)    收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示