object - 对重新分配的静态对象引用进行 GC
问题描述
假设我有obj = new myobject()
, whereobj
被声明为另一个非静态类实例中的静态类字段。过了一会儿,我在同一个静态变量上创建了一个新的 myobject obj
,从而“覆盖”了原来的赋值。
以下是我的问题:
- 分配的对象实例是否被 GC 可靠地释放,假设它不再可以从其他任何地方访问?
- 如果该字段被声明为非静态的,是否有任何区别?
- 在将静态 var 重新分配给新实例之前将其设置为 null 是否有区别?
解决方案
... where
obj
被声明为另一个非静态类实例中的静态类字段。
这可能意味着两件事之一;static
字段或类的实例字段static
。
以下内容适用于这两种情况,除非另有说明。
1) 分配的对象实例是否被 GC 可靠地释放,假设它不再可以从其他任何地方访问?
这取决于您所说的“可靠”是什么意思。实际上并不能保证 GC 将运行(永远),或者它会在给定的运行中找到所有无法访问的对象,或者在程序的生命周期中将收集一个无法访问的对象。
但是您通常不需要保证这些东西。真正重要的是,您不会因为某些无法访问的对象而耗尽堆空间1。
2)如果该字段被声明为非静态的,是否有任何区别?
这就是我一开始提到的问题发挥作用的地方:
如果我们谈论的字段是
static
类的实例字段,那么它已经是非静态的。如果我们谈论的是
static
字段与实例字段,那么各个字段的生命周期就会有所不同。一个static
字段在应用程序期间是可访问的(如果我们忽略动态创建的类加载器)。实例字段与它所属的对象一样长。
3)在将2静态变量重新分配给新实例
null
之前将其设置为有什么不同吗?
它没有任何区别。
1 - 我们需要在这里小心一点。JVM 可以触发“内存不足”事件,要么是因为内存不足,要么是因为 GC 花费了太多时间来收集垃圾。在后一种情况下,有可能(至少在理论上)在事件之前找不到给定的不可访问对象。也可以使用 Epsilon 收集器运行 JVM。这个收集器从不收集任何垃圾。
2 - 注意:您为变量赋值,而不是相反。您也可以说为变量分配了一个值。但不是你写的。使用正确的词语有助于(你的)理解。
推荐阅读
- c++ - 对于 C++,有 std::strchr() 的任何现代替代品吗?
- node.js - 如何使用 node.js(Firefox 或 Chrome)在 Heroku 上运行 Selenium-Webdriver
- uitableview - 在 javafx 中的 tableView 中自定义 TableCell
- amazon-web-services - 与 aws-cli s3 同步的文件模式匹配
- python - Python通过串口将数据写入Vellemank8090
- c# - 如何通过标识符(名称,Uid ...)访问用户控件?
- mysql - 查询以查找与同事超过 x 次的员工及其部门对
- java - 如果 db 中的布尔值不为 0,则相同的查询不返回任何内容
- r - 尝试创建一个函数,您可以在最终的 excel 电子表格中合并列中的行
- amazon-dynamodb - DynamoDB 中的多表与复合键