有效的Java说:
内存泄漏的第三个常见来源是侦听器和其他回调.如果您实现客户端注册回调但未明确注销回调的API,则除非您采取某些操作,否则它们将累积.确保回调被及时垃圾回收的最佳方法是仅存储对它们的弱引用,例如,通过仅将它们存储为WeakHashMap中的键.
我是Java的初学者.有人可以教我如何在回调中创建弱引用并告诉我它们如何解决内存泄漏问题?谢谢.
我想在一个对象中存储一个归零的弱引用NSDictionary.这是为了引用父项NSDictionary,因此我可以在不进行搜索的情况下爬回大型结构.
我不能__weak在这里使用; 即使我的本地引用很弱,它NSDictionary也会存储对弱引用对象的强引用.而且,当然,NSDictionary不能有nil对象.
我在iOS上,而不是Mac,因此NSHashTable无法使用.我只希望一个物体变弱; 其余的应该仍然很强大.
(我将发布我的答案,所以如果没有更好的答案,我有一些标记为可接受.但我希望有人有更好的答案.)
我知道弱引用受到垃圾收集器的支配,我们不能保证弱引用会存在.我看不出需要弱参考,但确定应该有理由.
在Django文档说这个关于这个问题:
另请注意,Django默认将信号处理程序存储为弱引用,因此如果您的处理程序是本地函数,则可能是垃圾回收.要防止这种情况,请在调用信号的connect()时传递weak = False.
我无法找到为什么这是默认值的任何理由,我不明白为什么你会希望你明确注册的信号隐式消失.那么弱引用的用例是什么?为什么它是默认值?
我意识到在99%的情况下这两种方式都没关系,但显然我在这里有一些不明白的东西,我想知道是否有任何"陷阱"潜伏在某一天可能会让我感到困惑.
python django garbage-collection weak-references django-signals
基本的不同之处在于,应该在每次运行GC时声明弱引用(保持内存占用率低),而软引用应该保留在内存中,直到GC实际需要内存(它们尝试扩展生命周期但可能随时失败,这对于例如特别是相当昂贵的对象的高速缓存是有用的.
据我所知,没有明确的陈述说明弱引用如何影响.NET中对象的生命周期.如果它们是真正的弱参考,它们根本不应该影响它,但是这也会使它们对于我们认为缓存的主要目的而言毫无用处(我错了吗?).另一方面,如果他们的行为像软参考,他们的名字有点误导.
就个人而言,我想他们的行为就像软参考,但这只是一种印象,而不是创立.
当然,实施细节也适用.我问的是与.NET的弱引用相关的心态 - 它们是否能够延长寿命,还是它们的行为像真正的弱引用?
(尽管有一些相关的问题我还没找到这个具体问题的答案.)
有人可以在Delphi中提供弱引用的解释吗?
我注意到这个概念经常在我仔细研究的一些库/框架源代码中提到.我陷入了困境,希望对它有一个明确的理解.
请考虑以下代码:
from weakref import ref
class Klass(object):
# __slots__ = ['foo']
def __init__(self):
self.foo = 'bar'
k = Klass()
r = ref(k)
Run Code Online (Sandbox Code Playgroud)
它可以工作,但当我取消注释__slots__它TypeError: "cannot create weak reference to 'Klass' object"在Python 2.6下打破.
请问,有没有人知道这是否是Python的固有限制,__slots__或者它是否是一个错误?如何解决它?
在我参与的其中一个项目中,有大量使用WeakAction.这是一个类,它允许保持对动作实例的引用,而不会导致其目标不被垃圾回收.它的工作方式很简单,它在构造函数上执行操作,并保持对操作的目标和方法的弱引用,但丢弃对操作本身的引用.当执行操作时,它会检查目标是否仍然存活,如果是,则调用目标上的方法.
除了一个案例 - 当一个闭包中实例化动作时,一切都很好.考虑以下示例:
public class A
{
WeakAction action = null;
private void _register(string msg)
{
action = new WeakAction(() =>
{
MessageBox.Show(msg);
}
}
}
Run Code Online (Sandbox Code Playgroud)
由于lambda表达式使用msg局部变量,因此C#编译器会自动生成一个嵌套类来保存所有闭包变量.该操作的目标是嵌套类的实例而不是A的实例.WeakAction一旦构造函数完成,就不会引用传递给构造函数的操作,因此垃圾收集器可以立即处理它.稍后,如果WeakAction执行,它将无法工作,因为目标不再存在,即使原始实例A是活着的.
现在我无法改变WeakAction被调用的方式(因为它被广泛使用),但我可以改变它的实现.我正在考虑尝试找到一种方法来访问A的实例,并强制嵌套类的实例保持活着,而A的实例仍然存活,但我不知道该怎么做.
关于什么A与任何事情有关,有很多问题,改变方式的建议A会产生一个弱行动(我们做不到),所以这里有一个澄清:
类A的实例希望类的实例B在发生某些事件时通知它,因此它使用Action对象提供回调.A不知道B使用弱动作,它只是提供一个Action作为回调.这事实上B使用WeakAction是一个实现细节不暴露.B需要存储此操作并在需要时使用它.但是B可能活得更久A,并且持有对正常Action的强引用(它本身拥有A生成它的实例的强引用)导致A永远不会被垃圾收集.如果A是不再存活的项列表的一部分,我们期望A被垃圾收集,并且由于BAction 的引用,它本身指向 …
有了闭包,我通常将[弱自我]附加到我的捕获列表上,然后对self进行空检查:
func myInstanceMethod()
{
let myClosure =
{
[weak self] (result : Bool) in
if let this = self
{
this.anotherInstanceMethod()
}
}
functionExpectingClosure(myClosure)
}
Run Code Online (Sandbox Code Playgroud)
如果我使用嵌套函数代替闭包,我该如何对self执行null检查(或者检查甚至是必要的......或者使用像这样的嵌套函数甚至是好的做法)即
func myInstanceMethod()
{
func nestedFunction(result : Bool)
{
anotherInstanceMethod()
}
functionExpectingClosure(nestedFunction)
}
Run Code Online (Sandbox Code Playgroud) memory-management weak-references nested-function swift capture-list
weak-references ×10
c# ×3
.net ×2
java ×2
python ×2
callback ×1
capture-list ×1
delphi ×1
django ×1
events ×1
ios ×1
nsdictionary ×1
swift ×1