黑马程序员技术交流社区

标题: 写一个Java内存泄漏代码 [打印本页]

作者: 张鹏宇    时间: 2014-5-16 16:11
标题: 写一个Java内存泄漏代码
package Memory;

import java.util.ArrayList;

public class MemoryLeak {
        public static void main(String[] args){
                ArrayList list = new ArrayList();
        for(int i=0;i<1000;i++)
                list.add(new String(new char[50000]).substring(1,5));
        }
}
这个是JDK1.6本身存在的内存泄漏代码。1.7已修复,研究了一段时间搞明白了几种内存区域的溢出,内存泄漏还真没什么经典的例子,谁能举个例子
作者: caijunsong    时间: 2014-5-16 16:38
  1. package cn.heima.test;

  2. import java.util.HashSet;

  3. class Person
  4. {
  5.         String name;//为了演示方便就不私有化了
  6.         int age;
  7.         Person(String name,int age)
  8.         {
  9.                 this.name=name;
  10.                 this.age=age;
  11.         }
  12.         //以哈希表为底层结构的集合是通过复写一下两个方法来保证元素的唯一性
  13.         @Override
  14.         public int hashCode()
  15.         {
  16.                 return name.hashCode()*age;
  17.         }
  18.         @Override
  19.         public boolean equals(Object obj)
  20.         {
  21.                 Person p=(Person)obj;
  22.                 return this.name.equals(p.name)&&this.age==p.age;
  23.         }
  24.         public String toString()
  25.         {
  26.                 return "name:"+name+"age:"+age;
  27.         }
  28. }
  29. public class Demo {

  30.         /**
  31.          * 用HashSet集合演示内存泄漏!!
  32.          */
  33.         public static void main(String[] args) {
  34.                 // TODO Auto-generated method stub
  35.      HashSet<Person> hs=new HashSet<Person>();
  36.      Person p=new Person("张三",25);
  37.      hs.add(new Person("小杨",22));
  38.      hs.add(p);
  39.      hs.add(new Person("李四",23));
  40.      hs.add(new Person("王五",26));
  41.      //演示:这里是显示添加进去元素的内容
  42.      System.out.println(hs);
  43.      //[name:小杨age:22, name:王五age:26, name:张三age:25, name:李四age:23]
  44.      p.age=27;
  45.      hs.remove(p);
  46.      //在集合中的张三年龄被改成了27 但是我们结果显示张三是无法被删除的
  47.      System.out.println(hs);
  48.    /*  原因:因为原先的放入集合中的Person对象的哈希值是通过其属性计算得到的,我们修改了其属性,
  49.      但它的哈希值并不是自动跟着变化,而是已经固定下来了,当我们要删除这个修改过的对象元素时,会发现我们计算的
  50.      哈希值是不会和它固定的哈希值相同的,因此原先的元素就怎么样也删除不了,所以我们说以哈希表为底层数据结构的
  51.      集合是禁止修哪些参与计算哈希值的属性    所谓内存泄漏不就是开辟的内存无法被释放  这个例子演示了内存泄漏
  52.      也讲解了以哈希表为数据结构的注意事项*/
  53.         }

  54. }
复制代码

作者: 张鹏宇    时间: 2014-5-16 18:45
caijunsong 发表于 2014-5-16 16:38

赞,给我了一种新的思路
作者: 大漠孤烟    时间: 2014-5-16 20:30
学习啦,楼主很细心、、、、、
作者: weimoliang    时间: 2014-5-16 21:35
caijunsong 发表于 2014-5-16 16:38

嗯嗯  嗯嗯 不错,理解到位!!
作者: 墨香    时间: 2014-5-17 23:07
Java尽管采用自动的内存管理方式,但是仍然存在泄露的可能,我们知道JVM认为对象没有引用时,会把这个对象视为垃圾。

  Java内存泄露就存在于,这个对象实际上已经不再需要,但是仍然存在引用,此时就会产生内存泄露。

  Stack的内存泄露

  下面是Stack的Pop方法,pop方法的作用是弹出栈最上面的对象,并释放这个对象的内存。

  下面的代码可以看到,只是返回了栈最上面的对象,但是由于数组仍然对对象存在引用,因此这个对象不会被GC回收

  public Object pop(){

  if( size == 0)

  throw new EmptyStackException();

  return elements[--size];

  }

  看看java.util.Stack中的实现,

  public synchronized E pop() {

  E    obj;

  int    len = size();

  obj = peek();

  removeElementAt(len - 1);

  return obj;

  }

  public synchronized void removeElementAt(int index) {

  modCount++;

  if (index >= elementCount) {

  throw new ArrayIndexOutOfBoundsException(index + " >= " +

  elementCount);

  }

  else if (index < 0) {

  throw new ArrayIndexOutOfBoundsException(index);

  }

  int j = elementCount - index - 1;

  if (j > 0) {

  System.arraycopy(elementData, index + 1, elementData, index, j);

  }

  elementCount--;

  elementData[elementCount] = null; /* to let gc do its work */

  }

 实际上就是释放了数组对对象的引用,因而,避免了内存泄露

作者: 张鹏宇    时间: 2014-5-18 22:49
求各种思路啊
作者: 路漫漫_求索    时间: 2014-5-21 23:03
package cn.itcast.day1;


作者: 张鹏宇    时间: 2014-5-22 09:14
路漫漫_求索 发表于 2014-5-21 23:03
package cn.itcast.day1;

  • 和2楼一样的思路





    欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2