我读过一个blog post(对不起,它用中文写的),作者说:
这是一个与网络相关的应用,当用户
完成一些操作后,这些变量将被设置为某个值以供以后使用。
该应用正常运行良好,但是当我们使用
大量的JavaScript,我们的应用程序开始无法正常工作,
意外(没有任何活动切换),我们找不到原因。
最后,我们发现这是由整数变量引起的
设置为零。但是我们非常确定我们的代码不会将其重置为
零,因此只有一个可能的结论:“为了满足
WebView所需的资源,垃圾收集器已经收集了我们的
变量”。因此,最后我们将此变量设置为静态变量,以避免出现此问题。
坦率地说,这个“ GC将一个int设为零”的说法与我的Java知识完全相反。
因为据我所知:
Java GC的收集单元是对象,而基本类型int在Java中不是对象。
实例变量的生命周期与所有者对象的生命周期相同,并且当GC收集了该对象变量时,该实例变量的内存使用将被释放。
即使该变量是Integer对象,而不是原始int,也因此可以收集,只要有对它的可达引用,就不会收集它。
即使我们使用WeakReference来存储Integer引用,以使该Integer对象可收集,在收集完Integer对象之后,无论如何我们都无法访问该已释放对象的内存。
但是我也担心是否有我没有考虑的东西。
所以我对以下问题非常感兴趣:
我是否可能由于垃圾回收而将int或Integer对象重置为零?
GC是否可能仅释放对象占用的部分内存空间(例如仅一个实例变量),而不是全部对象?
是否可以引用一个已经被垃圾回收的对象,如果我们取消引用该对象会发生什么?
在这种情况下,最有可能发生的情况是假设变量被随机重置为零,而不是由其代码引起的。虚拟机错误? GC错误? JIT错误还是其他?
最佳答案
我是否可能由于垃圾回收而将int或Integer对象重置为零?
如果持有int
或Integer
本身的对象被垃圾回收,后来又由应用程序代码重新创建,则在外部看来int
或Integer
已被重置。
否则,不会。
GC是否可能仅释放对象占用的部分空间,而不是全部对象?
仅当您使用诸如WeakReference
之类的东西作为与“部分空间”的连接时。
是否可以引用已经被垃圾收集的对象
不可以。如果可以到达,就不能进行垃圾回收。
如果我们取消引用将会怎样?
时空连续体将破裂,终结我们所知的现实。