2

我只是想知道当我声明和初始化一个变量并随后用其他值(例如 ArrayList 或类似的东西)再次初始化它时,我的程序背后会发生什么。

当我这样说时,我的 RAM 中会发生什么:

ArrayList<String> al = new ArrayList<String>();
...add values, work with it and so on....

al = new ArrayList<String>();

那么我的第一个 ArrayList 是保存在 RAM 中还是将第二个 ArrayList 存储在第一个 ArrayList 之前的位置?或者它会改变“al”的引用吗?

如果它没有被替换......有没有办法手动释放第一个arraylist占用的RAM?(无需等待垃圾收集器)首先设置它是否有帮助=null?

很好的问候,波斯克伦

4

3 回答 3

4

新的 ArrayList 将从内存的某个不同部分分配,引用更改为指向它,如果旧的 ArrayList 不再被其他东西引用,它将被垃圾收集。在 Java 中无法手动释放内存。它自动发生。

将变量设置为 null 是无关紧要的,当它在此之后立即设置为其他变量,或者它是一个无论如何都会很快超出范围的局部变量(但在 ArrayList 等数据结构中,将包含的数组的元素设置为 null,当元素为删除,是避免内存泄漏所必需的)。

于 2010-05-10T06:53:05.497 回答
4

您发布的代码将分配一个新的 ArrayList 实例。如果你想重用同一个,你可以这样做:

ArrayList<String> al = new ArrayList<String>();
...add values, work with it and so on....

al.clear();
// now you can use a1

但是请谨慎执行此操作 - 如果您将初始实例传递a1给将使用它较长时间的其他代码,那么清除它会导致问题,您将需要一个单独的实例。

但还要注意,从回收对象数组和 ArrayList 中获得的节省并不是那么好。如果您在 ArrayList 中存储 10 x 4096 字节的字符串,则数组列表本身仅占用与引用大小成比例的空间,例如大约 4 字节 x 10 = 40 字节。这是一种简化,但原理是正确的。因此,即使您重用相同的数组列表,您也只是为自己节省了用于存储对象引用的内存,而不是对象本身。考虑到这一点,以及无意中修改集合导致错误的风险,我猜大多数人不会打扰回收列表。

现代 VM 中的内存管理确实非常好,只有在看到有需要时才应该开始引入内存“优化”。事实上,使用对象的时间超过其自然生命周期会对垃圾收集性能产生负面影响。

我的建议是,首先清楚地编写代码,分析,并仅在您发现问题并确定原因时才专注于优化内存使用。

祝你好运!

于 2010-05-10T07:13:24.203 回答
1

堆中的新空间将分配给新的 ArrayList。

您不能强制进行垃圾收集,并且分配 null 只会消耗处理器周期。您可以致电System.gc()建议 JVM 运行垃圾收集器,但不能保证。

于 2010-05-10T06:52:44.313 回答