Ant*_*th0 13 java collections performance garbage-collection
关于Java Web应用程序性能的一个小问题.
我们假设我有List<Rubrique> listRubriques十个Rubrique对象.
A Rubrique包含一个products(List<product> listProducts)列表和一个clients(List<Client> listClients)列表.
如果我这样做,内存中究竟会发生什么:
listRubriques.clear(); listRubriques = null;
Run Code Online (Sandbox Code Playgroud)
我的观点是,因为listRubriques是空的,所以此列表之前引用的所有对象(包括listProducts和listClients)很快就会被垃圾收集.但是因为Java中的Collection有点棘手,因为我的应用程序存在相当大的性能问题,我问的问题是:)
编辑:我们现在假设我的客户端对象包含一个List<Client>.因此,我的对象之间有一个循环引用.如果我listRubrique被设置为什么会发生什么null?这一次,我的观点是我的客户端对象将变得"无法访问"并可能造成内存泄漏?
Mne*_*nth 15
Java的实际Sun实现不时复制所有引用/生存对象.然后,复制的空间可以再次用于内存分配.
那说你的例子会损害实际的表现.listRubriques.clear()是不需要的(除了你在其他地方有一个对它的引用),因为listRubrique引用的所有内容都是垃圾,不再引用listRubriques.listRubriques = null如果变量listRubriques之后超出范围(可能因为它是局部变量并且方法在此结束),也可能不需要.
不仅不需要清除调用,因为clear访问后来不再使用的对象的内存,访问对象并且现代处理器将其放入缓存中.因此,死对象明确地转到处理器缓存 - 一些可能更有用的数据将被覆盖用于该操作.
本文是获取有关Java垃圾收集器的更多信息的一个很好的参考.
编辑:对问题中的编辑作出反应:垃圾收集器(至少由Sun使用的实现)从一些根引用开始,并复制它可以从此引用到达的所有对象以及复制对象引用的对象.所以你的循环引用对象是垃圾,因为没有'外部'引用指向它们,内存将在垃圾收集中回收.
如果你有:
listRubriques = null;
Run Code Online (Sandbox Code Playgroud)
并且没有其他对象持有对其listRubriques或其包含对象的引用,因此它有资格进行垃圾收集。但无法保证 JVM 何时真正对其运行垃圾收集并释放内存。您可以致电:
System.gc();
Run Code Online (Sandbox Code Playgroud)
向 JVM 推荐您认为此时运行垃圾收集是一个好主意。但即便如此,也不能保证。
还拥有
listRubriques.clear();
Run Code Online (Sandbox Code Playgroud)
在设置listRubriques为之前null没有必要。
编辑:为了回答关于循环引用的问题,JVM 足够聪明,可以发现整个对象图与任何活动运行的代码都断开连接,并且 JVM 将正确确定它们都符合垃圾收集的条件。即使在引用计数的糟糕时代,这也一直是正确的。现代 JVM 更快、更高效。但它们并不比旧版 JVM 收集更多的对象。