我读过一个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对象重置为零?


如果持有intInteger本身的对象被垃圾回收,后来又由应用程序代码重新创建,则在外部看来intInteger已被重置。

否则,不会。


  GC是否可能仅释放对象占用的部分空间,而不是全部对象?


仅当您使用诸如WeakReference之类的东西作为与“部分空间”的连接时。


  是否可以引用已经被垃圾收集的对象


不可以。如果可以到达,就不能进行垃圾回收。


  如果我们取消引用将会怎样?


时空连续体将破裂,终结我们所知的现实。

09-04 09:57
查看更多