我只是想知道当我声明并初始化变量并稍后使用其他值再次初始化时,我的程序背后会发生什么,例如一个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? (无需等待垃圾收集器) 将它设置为first = null会有帮助吗?
很高兴的问候, poeschlorn
答案 0 :(得分:4)
新的ArrayList将从内存的某些不同部分进行分配,引用将更改为指向它,如果旧的ArrayList不再被其他内容引用,则它将被垃圾回收。没有办法在Java中手动释放内存。它会自动发生。
将设置变量设置为null是无关紧要的,当它被设置为其后的其他内容时,或者它是一个局部变量,它很快就会超出范围(但是在像ArrayList这样的数据结构内部,将包含的数组的元素设置为null,当删除元素,避免内存泄漏。
答案 1 :(得分:4)
您发布的代码将分配一个新的ArrayList实例。如果你想重复使用同一个,你可以这样做:
ArrayList<String> al = new ArrayList<String>();
...add values, work with it and so on....
al.clear();
// now you can use a1
但请谨慎行事 - 如果您将a1
的初始实例传递给将在更长时间内使用它的其他代码,那么清除它将导致问题,您将需要一个单独的实例。
但是请注意,从回收对象数组和ArrayLists中获得的节省并不是那么好。如果您在ArrayList中存储10 x 4096字节字符串,则数组列表本身仅占用与引用大小成比例的空间,例如大约4个字节x 10 = 40个字节。这是一种简化,但原则是正确的。因此,即使您重用相同的数组列表,您也只能节省用于存储对象引用的内存,而不是对象本身。考虑到这一点,以及通过无意中修改集合而导致错误的风险,我猜大多数人都不会打扰回收列表。
现代虚拟机中的内存管理确实非常好,当您发现需要它时,您应该只开始引入内存“优化”。实际上,使用对象的时间超过其自然生命周期会对垃圾收集性能产生负面影响。
我的建议是,首先清楚地编码,配置文件,并且只有在您发现存在问题并确定原因时才专注于优化内存使用。
祝你好运!答案 2 :(得分:1)
Heap中的新空间将分配给新的ArrayList。
您无法强制进行垃圾回收并且分配null只会占用处理器周期。你可以调用System.gc()
来建议JVM运行垃圾收集器,但是没有保证。