在像C ++这样的语言中,应用程序负责管理动态分配的内存所使用的内存。当使用new运算符在C ++堆中创建对象时,需要相应地使用delete运算符来处置该对象:
如果程序忘记了delete一个对象而只是“忘记”了该对象,则关联的内存将丢失给应用程序。这种情况的术语是内存泄漏,它会导致过多的内存泄漏,因此应用程序可能会使用越来越多的内存,并最终导致崩溃。
另一方面,如果应用程序尝试delete两次访问同一对象,或者在删除对象后使用该对象,则该应用程序很可能由于内存损坏问题而崩溃。
在复杂的C ++程序中,使用new和实现内存管理delete可能很耗时。确实,内存管理是错误的常见来源。
Java采用了不同的方法。deleteJava提供了一种称为垃圾回收的自动机制来回收不再需要的对象使用的内存,而不是显式的运算符。Java运行时系统负责查找要处置的对象。此任务由称为垃圾收集器(简称GC)的组件执行。
在执行Java程序的任何时候,我们都可以将所有现有对象的集合分为两个不同的子集1:
JLS定义可到达的对象,如下所示:
可达对象是可以从任何活动线程进行任何潜在的连续计算中访问的任何对象。
实际上,这意味着从范围内局部变量或static某些html" target="_blank">html" target="_blank">代码可能能够到达该对象的变量开始,存在一系列引用。
无法访问的对象是无法如上所述实现的对象。
这是不可达的任何对象都是有资格进行垃圾回收。这并不意味着它们将被垃圾收集。事实上:
无法到达的对象不会在无法到达时立即被收集1。
无法访问的对象可能永远不会被垃圾回收。
Java语言规范为JVM实现提供了很大的自由度,以决定何时收集无法访问的对象。在实践中,它还允许JVM实现保守地检测到无法访问的对象。
JLS保证的一件事是,将永远不会收集任何可到达的对象。
首先,当对象变得不可访问时,没有什么特别的事情发生。只有当垃圾收集器运行并且它检测到对象不可访问时,事情才会发生。此外,GC运行通常不会检测所有无法访问的对象。
当GC检测到无法访问的对象时,可能会发生以下事件。
如果有任何Reference引用该对象的对象,则将在删除该对象之前清除这些引用。
如果对象是可终结的,则它将被终结。这是在删除对象之前发生的。
可以删除该对象,并可以回收该对象占用的内存。
请注意,上面的事件可以按明确的顺序发生,但是不需要垃圾回收器在任何特定时间范围内对任何特定对象执行最终删除。
考虑以下示例类:
// A node in simple "open" linked-list. public class Node { private static int counter = 0; public int nodeNumber = ++counter; public Node next; } public class ListTest { public static void main(String[] args) { test(); // M1 System.out.prinln("Done"); // M2 } private static void test() { Node n1 = new Node(); // T1 Node n2 = new Node(); // T2 Node n3 = new Node(); // T3 n1.next = n2; // T4 n2 = null; // T5 n3 = null; // T6 } }
让我们检查一下当test()被调用时会发生什么。语句T1,T2和T3创建Node对象,以及对象是所有通过可到达n1,n2以及n3分别变量。语句T4将对第二个Node对象的引用分配给next第一个对象的字段。完成此操作后,Node可通过两条路径到达第二个:
n2 -> Node2 n1 -> Node1, Node1.next -> Node2
在语句T5中,我们将分配null给n2。这打破了的第一个可达性链Node2,但第二个保持不间断,因此Node2仍然可以实现。
在语句T6中,我们将分配null给n3。这打破了唯一的可达性链Node3,从而使它Node3无法实现。但是,Node1和Node2仍然可以通过n1变量访问。
最后,当test()方法返回时,它的局部变量n1,n2而n3走出去的范围,因此不能被任何东西所访问。这破坏了剩余的可达性链条Node1和Node2,和所有的Node对象也不可达,有资格进行垃圾回收。
1-这是一种简化,忽略了终结处理和Reference类。2-假设,Java实现可以做到这一点,但是这样做的性能代价使其不切实际。
主要内容:1 什么是Java 垃圾回收,2 Java 垃圾回收的优势,3 如何取消对象引用,4 finalize()方法,5 gc()方法,6 Java 垃圾回收的例子1 什么是Java 垃圾回收 在Java中,垃圾意味着未引用的对象。 垃圾回收是自动回收运行时未使用的内存的过程。换句话说,这是销毁未使用对象的一种方法。 我们在C语言中使用free() 函数,在C ++中使用delete()。但是,在Java中它是自动执行的。因此,java提供了更好的内存管理。 2 Java 垃圾回收的优势 它
问题内容: 我想知道Java中发生的垃圾回收。它真的能够处理所有未使用的对象并释放最大可能的内存吗? 我还想知道Java垃圾收集与另一种语言(例如C#)相比如何?然后,如何自动垃圾收集与从像C这样的语言中进行手动收集相比又能达到更好的效果呢? 问题答案: 是的,这就是垃圾收集的重点。 有许多不同形式的垃圾收集。如果不增强算法,最简单的形式即引用计数就无法处理某些类型的垃圾(循环引用)。 Java(
Kubernetes 垃圾收集器的角色是删除指定的对象,这些对象曾经有但以后不再拥有 Owner 了。 注意:垃圾收集是 beta 特性,在 Kubernetes 1.4 及以上版本默认启用。 Owner 和 Dependent 一些 Kubernetes 对象是其它一些的 Owner。例如,一个 ReplicaSet 是一组 Pod 的 Owner。具有 Owner 的对象被称为是 Owner
有人能给我解释一下原因吗?
垃圾回收 我们对生产中花了很多时间来调整垃圾回收。垃圾回收的关注点与Java大致相似,尽管一些惯用的Scala代码比起惯用的Java代码会容易产生更多(短暂的)垃圾——函数式风格的副产品。Hotspot的分代垃圾收集通常使这不成问题,因为短暂的(short-lived)垃圾在大多情形下会被有效的释放掉。 在谈GC调优话题前,先看看这个Attila的报告,它阐述了我们在GC方面的一些经验。 Scal
对于开发者来说,JavaScript 的内存管理是自动的、无形的。我们创建的原始值、对象、函数……这一切都会占用内存。 当我们不再需要某个东西时会发生什么?JavaScript 引擎如何发现它并清理它? 可达性(Reachability) JavaScript 中主要的内存管理概念是 可达性。 简而言之,“可达”值是那些以某种方式可访问或可用的值。它们一定是存储在内存中的。 这里列出固有的可达值的