阅读完这个问题之后,我想起了什么时候教我Java的,并且告诉我永远不要调用finalize()或运行垃圾回收器,因为“这是一个大黑盒子,您无需担心”。有人可以将其理由简化为几句话吗?我敢肯定,我可以阅读Sun的有关此事的技术报告,但是我认为一个不错的,简短的简单答案将满足我的好奇心。
简短的答案:Java垃圾回收是一个非常精细的工具。System.gc()是大锤。
Java的堆分为不同的世代,每个世代都是使用不同的策略收集的。如果将事件探查器附加到运行状况良好的应用程序,您会发现它很少需要运行最昂贵的集合,因为大多数对象是年轻一代中更快的复制收集器捕获的。
直接调用System.gc(),尽管从技术上讲不能做任何事情,但实际上将触发昂贵的,停止运行的全堆收集。这 几乎总是错误的做法
。您以为自己在节省资源,但实际上却没有充分的理由浪费它们,因此迫使Java重新检查所有活动对象,以防万一。
如果您在关键时刻出现GC暂停问题,最好将JVM配置为使用并发标记/清除收集器,该收集器是专门为最大程度地减少暂停时间而设计的,而不是尝试使用大锤解决问题,并且进一步打破它。
您正在考虑的Sun文档在这里:Java SE 6
HotSpot™虚拟机垃圾收集调优
(您可能不知道的另一件事:在您的对象上实现finalize()方法会使垃圾回收变慢。首先,将运行 两次
GC来收集对象:一次运行finalize(),第二次运行以确保该对象不存在。其次,具有finalize()方法的对象必须由GC视为特殊情况,因为它们必须单独收集,不能将它们大量丢弃。)
引用SCJP 6学习指南: 在方法中,您可以编写代码,将对所讨论对象的引用传递给另一个对象,从而有效地取消垃圾回收机制对该对象的资格。如果在同一对象稍后的某个时候再次有资格使用垃圾回收机制,垃圾回收器仍然可以处理并删除该对象。然而,垃圾回收器将记住,对于该对象,已经运行,并且不会再次运行 为什么设计成这样?方法的作用仍然有效,即使对象被第二次标记为收集。那么为什么Java决定跳过对的调用呢?
问题内容: 是什么决定了垃圾收集器何时真正收集?它是在一定时间之后还是在一定数量的内存用完之后发生的吗?还是还有其他因素? 问题答案: 它在确定是时候运行时运行。在世代垃圾收集器中,一种常见的策略是在第0代内存分配失败时运行收集器。也就是说,每次你分配一小块内存(大块通常直接放置在“旧”代中)时,系统都会检查gen-0堆中是否有足够的可用空间,如果没有,则运行GC释放空间以使分配成功。然后将旧数据
我从C代码中调用Java方法。每次调用时,我调用AttachCurrentThread,调用后,我调用DetachCurrentThread。 这可以很好地工作,但问题是,我看到了由此导致的ECSESSIVE垃圾收集,即几乎每个通过JNI的调用。VisualVM图形上的小集合基本上都是绿色的!从本机代码到Java的调用速率是每秒数百次。在调用过程中,我还可以看到创建了过多的Java线程,如Thre
我遇到了一个JNI程序随机内存不足的问题。 这是一个32位java程序,它读取文件,进行一些图像处理,通常使用250MB到1GB。然后丢弃所有这些对象,然后程序对通常需要100-250MB的JNI程序进行一系列调用。 当交互运行时,我从未见过问题。但是,当对许多文件连续运行批处理操作时,JNI程序将随机运行内存溢出。它可能对一个或两个文件有内存问题,然后对下一个10个文件运行正常,然后再次出现故障
Kubernetes 垃圾收集器的角色是删除指定的对象,这些对象曾经有但以后不再拥有 Owner 了。 注意:垃圾收集是 beta 特性,在 Kubernetes 1.4 及以上版本默认启用。 Owner 和 Dependent 一些 Kubernetes 对象是其它一些的 Owner。例如,一个 ReplicaSet 是一组 Pod 的 Owner。具有 Owner 的对象被称为是 Owner
问题内容: Python使用引用计数方法来处理对象生存期。因此,不再使用的对象将立即被销毁。 但是,在Java中,GC(垃圾收集器)会销毁在特定时间不再使用的对象。 Java为什么选择这种策略,这样做有什么好处? 这比Python方法更好吗? 问题答案: 使用引用计数存在弊端。最常提及的一种是循环引用:假设A引用B,B引用C和C引用B。如果A将其对B的引用删除,则B和C的引用计数仍为1,并且不会被