代码优化-避免内存泄漏的一次浅谈

1.代码场景

   当我们写java程序的时候,不可避免的需要一些集合操作,有时候使用不当,导致GC不能够回收释放被集合占用的内存,例如下面代码

protected List> findListBySql(String sql) {
		List> list = this.baseDao.findListBySql(sql);
		List> tempList = new LinkedList>();
		for (Map map : list) {
			Map tempMap;
			tempMap = new HashMap();
			tempList.add(tempMap);
			for (Map.Entry en : map.entrySet()) {
				tempMap.put(this.columnToField(en.getKey()), en.getValue());
			}
		}
	return tempList;
	}

  这个方法是用来查询数据库返回一个listMap的集合,因为数据库的字段和页面字段不完全一致,需要匹配替换,这里替换后的对象是tempList,原来的list对象不再使用,但是内存空间依旧被占用。对于此局部变量不再使用会造成内存泄漏。(即不能被调用也不能被释放)如下面的例子:

 public static void main(String[] args){
		 Map map = null;
		 map = new HashMap();
		 map.put("arr",new byte[1024*1024*8]);
         List> list;
         list= new LinkedList>();
         list.add(map);
        // clearMapList(list);
         System.gc();
	}

代码优化-避免内存泄漏的一次浅谈_第1张图片

2.集合清理

  集合类本身提供clear方法,HashMap的clear实现:

   public void clear() {
        Node[] tab;
        modCount++;
        if ((tab = table) != null && size > 0) {
            size = 0;
            for (int i = 0; i < tab.length; ++i)
                tab[i] = null;
        }
    }

 LinkedList的实现:

 public void clear() {
        // Clearing all of the links between nodes is "unnecessary", but:
        // - helps a generational GC if the discarded nodes inhabit
        //   more than one generation
        // - is sure to free memory even if there is a reachable Iterator
        for (Node x = first; x != null; ) {
            Node next = x.next;
            x.item = null;
            x.next = null;
            x.prev = null;
            x = next;
        }
        first = last = null;
        size = 0;
        modCount++;
    }

  根据两种类型的集合写一个清理方法如下:

	public static void clearMapList(List> list) {
		for (Map map : list) {
			map.clear();
		}
		list.clear();
	}

  测试方法效果:可以看到主动调用fullGC 老年代的对象自动释放了

代码优化-避免内存泄漏的一次浅谈_第2张图片

你可能感兴趣的:(java,jvm,GC,优化)