不可访问内存 Java四种引用包括强引用,软引用,弱引用,虚引用
小结:
1、不可访问内存是指一组没有任何可访问指针指向的由计算机程序进行动态分配的内存块。
2、垃圾收集器能决定是否一个对象还是可访问的;任何被确定不可访问的对象将会被释放。
术语对照表 — Python 3.13.0a0 文档 https://docs.python.org/zh-cn/dev/glossary.html#term-borrowed-reference
borrowed reference -- 借入引用
在 Python 的 C API 中,借入引用是指一种对象引用。 它不会修改对象引用计数。 如果对象被销毁则它会成为一个无目标指针。 例如,垃圾回收器可以移除对象的最后一个 strong reference 来销毁它。
推荐在 borrowed reference 上调用 Py_INCREF()
以将其原地转换为 strong reference,除非是当该对象无法在借入引用的最后一次使用之前被销毁。 Py_NewRef()
函数可以被用来创建一个新的 strong reference。
strong reference -- 强引用
在 Python 的 C API 中,强引用是对象引用的一种,当它被创建时将会增加对象引用计数而当它被删除时则会减少对象引用计数。
Py_NewRef()
函数可被用于创建一个对象的强引用。 通常,必须在退出某个强引用的作用域时在该强引用上调用 Py_DECREF()
函数,以避免引用的泄漏。
另请参阅 borrowed reference。
https://zh.wikipedia.org/wiki/不可访问内存
在计算机科学中,不可访问内存是指一组没有任何可访问指针指向的由计算机程序进行动态分配的内存块。类似的,一个不可访问对象是指没有可访问引用型指向的动态分配对象。通俗来说,不可访问内存是程序无法直接访问的动态内存,同时也无法通过指针指向一个可访问的起始对象来进行访问。
动态内存分配的实现是采用了垃圾回收机制,在一个对象不可访问后,它会被回收。垃圾收集器能决定是否一个对象还是可访问的;任何被确定不可访问的对象将会被释放。在许多编程语言中(例如:Java,C#,D语言,Dylan)都使用了自动垃圾回收机制。
相反的,在动态内存分配机制中,当需要明确释放的内存变得不可访问时,此内存可以不再明确释放。在使用人工内存管理中,系统中的不可访问内存会导致内存泄漏。
一些垃圾收集器使用弱引用。如果一个对象能够通过弱引用或者包含弱引用的链接,那么这个对象可以被称为弱访问。垃圾收集器能够把弱访问的对象图视为不可访问的,并且释放它。(反过来说,防止对象被当作垃圾收集的引用被称为强引用;通过只含有强引用的链接来访问的弱可访问对象是不可访问的。)一些垃圾回收的面向对象语言,例如Java和Python,拥有弱引用的特性。Java包java.lang.ref
提供了软引用,弱引用和虚引用,产生了其他对象访问状态可软访问和可虚访问。
不可访问内存往往和软件老化有关。
参见
外部链接
A useful discussion can be found at Ethan Nicholas's Blog
Unreachable memory - Wikipedia https://en.wikipedia.org/wiki/Unreachable_memory
In computer science, unreachable memory is a block of memory allocated dynamically where the program that allocated the memory no longer has any reachable pointer that refers to it. Similarly, an unreachable object is a dynamically allocated object that has no reachable reference to it. Informally, unreachable memory is dynamic memory that the program can not reach directly, nor get to by starting at an object it can reach directly, and then following a chain of pointer references.
In dynamic memory allocation implementations that employ a garbage collector, objects are reclaimed after they become unreachable. The garbage collector is able to determine if an object is reachable; any object that is determined to no longer be reachable can be deallocated. Many programming languages (for example, Java, C#, D, Dylan) use automatic garbage collection.
In contrast, when memory becomes unreachable in dynamic memory allocation implementations that require explicit deallocation, the memory can no longer be explicitly deallocated. Unreachable memory in systems that use manual memory management results in a memory leak.
Some garbage collectors implement weak references. If an object is reachable only through either weak references or chains of references that include a weak reference, then the object is said to be weakly reachable. The garbage collector can treat a weakly reachable object graph as unreachable and deallocate it. (Conversely, references that prevent an object from being garbage collected are called strong references; a weakly reachable object is unreachable by any chain consisting only of strong references.) Some garbage-collected object-oriented languages, such as Java and Python, feature weak references. The Java package java.lang.ref
supports soft, weak and phantom references, resulting in the additional object reachability states softly reachable and phantom reachable.
Unreachable memory is often associated with software aging.
External links
- Nicholas, Ethan (4 May 2006). "Understanding Weak References". java.net. Archived from the original on 19 August 2010. Retrieved 1 October 2010. External link in
|publisher=
(help)
Java四种引用包括强引用,软引用,弱引用,虚引用。 - 一步一个脚印,坚持 - 博客园
https://www.cnblogs.com/yw-ah/p/5830458.html
https://zh.wikipedia.org/wiki/弱引用
在计算机程序设计中,弱引用与强引用相对,是指不能确保其引用的对象不会被垃圾回收器回收的引用。一个对象若只被弱引用所引用,则被认为是不可访问(或弱可访问)的,并因此可能在任何时刻被回收。一些配有垃圾回收机制的语言,如Java、C#、Python、Perl、Lisp等都在不同程度上支持弱引用。
垃圾回收用来清理不会再使用的对象,从而降低内存泄露和数据损坏的可能性。垃圾回收主要有两种类型:追踪和引用计数。引用计数会记录给定对象的引用个数,并在引用个数为零时收集该对象。由于一次仅能有一个对象被回收,引用计数无法回收循环引用的对象。一组相互引用的对象若没有被其它对象直接引用,并且不可访问,则会永久存活下来。一个应用程序如果持续地产生这种不可访问的对象群组,就会发生内存泄漏。在对象群组内部使用弱引用(即不会在引用计数中被计数的引用)有时能避免出现引用环,因此弱引用可用于解决循环引用的问题。如Apple的Cocoa框架就推荐使用这种方法,具体为,在父对子引用时使用强引用,子对父引用时使用弱引用,从而避免了循环引用。[1]
程序对一些对象只进行弱引用,通过此法可以指明哪些对象是不重要的,因此弱引用也用于尽量减少内存中不必要的对象存在的数量。
有些语言包含多种强度的弱引用。例如Java,在java.lang.ref[1]包中定义了软引用、弱引用和虚引用,引用强度依次递减。每种引用都有相对应的可访问性概念。垃圾回收器(GC)通过判断对象的可访问性类型来确定何时回收该对象。当一个对象是软可访问的,垃圾回收器就可以安全回收这个对象,但如果垃圾回收器认为JVM还能空出可用内存(比如JVM还有大量未使用的堆空间),则有可能不会立刻回收软可访问的对象。但对于弱可访问的对象,一旦被垃圾回收器注意到,就会被回收。和其他引用种类不同,虚引用无法跟踪。但另一方面,虚引用提供了一种机制,当一个对象被回收时程序可以得到通知(实现于ReferenceQueues)。 一些未配有垃圾回收机制的语言,比如C++,也提供强/弱引用的功能,以作为对垃圾回收库的支持。在C++中,普通指针可看做弱引用,智能指针可看做强引用,尽管指针不能算"真正"的弱引用,因为弱引用应该能知道何时对象变成不可访问的了。
Java是第一个将强引用作为默认对象引用的主流语言。之前的(ANSI)C语言只支持弱引用。而后David Hostettler Wain和Scott Alexander Nesmith注意到事件树无法正常释放的问题,结果在大约1998年,推出了分别会被计数和不会被计数的强、弱引用。 如果创建了一个弱引用,然后在代码的其它地方用 get()
获得真实对象,由于弱引用无法阻止垃圾回收,get()
随时有可能开始返回 null
(假如对象没有被强引用)。[2]
import java.lang.ref.WeakReference;
public class ReferenceTest {
public static void main(String[] args) throws InterruptedException {
WeakReference r = new WeakReference(new String("I'm here"));
WeakReference sr = new WeakReference("I'm here");
System.out.println("before gc: r=" + r.get() + ", static=" + sr.get());
System.gc();
Thread.sleep(100);
//只有r.get()变为null
System.out.println("after gc: r=" + r.get() + ", static=" + sr.get());
}
}
弱引用还可以用来实现缓存。例如用弱哈希表,即通过弱引用来缓存各种引用对象的哈希表。当垃圾回收器运行时,假如应用程序的内存占用量高到一定程度,那些不再被其它对象所引用的缓存对象就会被自动释放。
Lua
weak_table = setmetatable({}, {__mode="v"})
weak_table.item = {}
print(weak_table.item)
collectgarbage()
print(weak_table.item)
https://baike.baidu.com/item/弱引用/1019312
垃圾回收
变种
示例
Java
1
|
import java.lang.ref.WeakReference; public class ReferenceTest { public static void main(String[] args) throws InterruptedException { WeakReference r = new WeakReference( new String( "I'm here" )); WeakReference sr = new WeakReference( "I'm here" ); System.out.println( "before gc: r=" + r.get() + ", static=" + sr.get()); System.gc(); Thread.sleep(100); //只有r.get()变为null System.out.println("after gc: r=" + r.get() + ", static=" + sr.get()); }} |