1

我正在使用单例在运行时授予每个对象的唯一副本:

Car object1= CarFactory.createCar(id);

其中 createCar 方法是:

private static ArrayList<Car> cars= new ArrayList<Car>();

public static synchronized Car createCar(int id){
   Car result= new Car(id);
   int index= cars.indexOf(result);
   if (index==-1){
      cars.add(result);
      return result;
   } else {
      return cars.get(index);
   }
}

问题是,使用这种方法,由于“汽车”集合,每辆汽车总是有一个引用,并且对象的内存永远不会被释放。我该如何改进它?

4

3 回答 3

2

WeakReference在将对象放入列表之前,使用 a包装对象。例子:

private static List<WeakReference<Car>> cars = new ArrayList<WeakReference<Car>>();

public static synchronized Car createCar(int id) {
   WeakReference<Car> result= new WeakReference<Car>(new Car(id));
   int index= cars.indexOf(result);
   if (index==-1){
      cars.add(result);
      return result.get();
   } else {
      return cars.get(index).get();
   }
}

注意:这不是生产代码。在使用它之前,您必须建立更多的保护措施。

于 2012-04-08T19:51:16.707 回答
1

你可以保留一个WeakReferences 的列表。弱引用不足以防止对象被垃圾收集。

前任:

    List<WeakReference<Point>> list = new ArrayList<>();
    Point p = new Point();
    list.add(new WeakReference<>(p));
    System.out.println(p);
    System.out.println(list.get(0).get());

    p = null;

    System.gc();
    System.gc();
    System.gc();
    System.gc(); // hopefully the GC collects p by now

    System.out.println(list.get(0).get()); // null!

但是,除非您要创建大量Cars 并且内存实际上是一个问题,否则可能不值得麻烦。

于 2012-04-08T19:52:44.873 回答
1

这有点像黑客,但你可以使用

WeakHashMap<Car,WeakReference<Car>> cars=new WeakHashMap<Car,WeakReference<Car>>();

public static synchronized Car createCar(int id){
   Car result= new Car(id);
   WeakReference<Car> weakCar=cars.get(result);
   if(weakCar==null){
       cars.put(new WeakReference(result));
       return result;
   }
   Car val= weakCar.get();
   if (val==null){//it may have been collected between cars.get() and weakCar.get()
      cars.put(new WeakReference(result));
      return result;
   } else {
      return val;
   }
}

请注意,您需要弱引用作为值,因为该值被认为是强引用

于 2012-04-08T20:04:42.407 回答