如何在Java中正确清除

时间:2019-07-02 09:57:44

标签: java arraylist garbage-collection clear

当我在另一个对象中进一步引用了对象时,如何在Java中正确清除。假设我有以下示例:

大陆 | ________国家          | ______城市

因此,一个大洲可以有多个国家,而这些国家又可以有多个城市。

 public class City {
      public String name;

      public City(String name) {
          this.name = name;
      }
 }

 public class Country {
      public String name;
      public ArrayList<City> cities = new ArrayList<City>();

      public Country(String name) {
          this.name = name;
      }
 }

 public class Continent {
     public String name;
     public ArrayList<Country> countries = new ArrayList<Country>();

     public Country(String name) {
         this.name = name;
     }
 }

 public static void main(String[] args) {
     City city1 = new City("Berlin");
     City city2 = new City("Paris");
     City city3 = new City("Munich");

     Country country1 = new Country("Germany");
     Country country2 = new Country("France");

     country1.cities.add(city1);
     country1.cities.add(city3);

     country2.cities.add(city2);

     Continent continent1 = new Continent("Europe");
     continent1.countries.add(country1);
     continent1.countries.add(country2);
 }

如您所见,我有一个Continent对象,该对象在ArrayList中具有多个国家,每个国家又可以具有多个Cities。现在我的问题是:

据我所知,垃圾收集器不会碰到引用的对象,因此我必须确保删除所有引用。所以,当我没错的时候,

continent1.countries.clear();

是不够的。在这种情况下,如果我清除对象大陆中的ArrayList“ countries”和每个对象Country中的所有ArrayLists“ cities”,就足够了吗?还是我错过了什么,或者我完全错了?

1 个答案:

答案 0 :(得分:0)

您对垃圾收集器工作方式的理解存在缺陷。

大多数算法(有很多不同的算法)都始于创建一组可引用对象的根。那就是堆栈,寄存器等中的那些对象。根集中的每个对象都标记为活动对象,然后递归地跟踪(并标记)对其他对象的引用。这样可以确保识别所有可引用对象(无论深度如何)。这称为精确收集器。

然后,收集器可以回收不再需要的对象(即未标记为活动的)使用的空间。这种情况如何发生取决于对象是年轻一代还是老一代,以及所使用的算法(CMS,并行,G1等)。

在您的情况下,您将维护对所有对象的单独引用,因此即使不再引用continent1,也不会收集“国家和城市”对象。如果对Country和City对象的唯一引用是通过Continent对象,则可以在收集continent1时收集它们。

这里的关键点是,开发人员不需要在不再需要对象时告诉JVM和GC的任何责任。这一切都是自动发生的。