- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的应用程序中有一个 WeakReference 的静态列表。在某个时候,我想拍摄此列表中所有当前“事件”对象的快照。
代码是这样的:
private static readonly List<WeakReference> myObjects = new List<WeakReference>();
public static MyObject[] CollectObjects()
{
var list = new List<MyObject>();
foreach (var item in myObjects)
{
if (!item.IsAlive)
continue;
var obj = item.Target as MyObject;
list.Add(obj);
}
return list.ToArray();
}
我遇到的问题是有时(很少)在上面的 foreach 循环中出现“集合已修改”异常。我只在 MyObject 构造函数/终结器中从这个列表中添加/删除,它看起来像这样:
public class MyObject
{
private static readonly object _lockObject = new object();
WeakReference referenceToThis;
public MyObject()
{
lock (_lockObject)
{
referenceToThis = new WeakReference(this);
myObjects.Add(referenceToThis);
}
}
~MyObject()
{
lock (_lockObject)
{
myObjects.Remove(referenceToThis);
}
}
}
由于我的代码中没有任何其他内容触及列表,因此我假设垃圾收集器正在完成其中一些对象,就像我尝试枚举列表一样。
我考虑过在 foreach 循环周围添加一个 lock (_lockObject)
但我不确定这样的锁会如何影响 GC?
是否有更好/正确/更安全的方法来枚举弱引用列表?
最佳答案
终结器在整个垃圾回收机制中引入了显着的开销,因此最好尽可能避免使用它。在您的情况下,您可以避免它并大大简化您的设计。
不是让你的对象通过终结器检测自己的终结并将自己从该列表中删除,而是替换你的 List<WeakReference<T>>
用WeakCollection<T>
.
WeakCollection<T>
是一个集合,而不是一个列表。永远不要在集合就足够的地方使用列表。
WeakCollection<T>
完全封装了它包含弱引用的事实,这意味着您将它用作常规列表,其接口(interface)中没有任何关于弱引用的内容。
WeakCollection<T>
当它检测到它们已经过期时,自动从自身中删除弱引用。 (您会发现将其实现为列表比将其实现为集合要复杂得多,所以再说一遍——永远不要在集合就足够的地方使用列表。)
这是一个 WeakCollection<T>
的示例实现.当心:我还没有测试过。
namespace Whatever
{
using Sys = System;
using Legacy = System.Collections;
using Collections = System.Collections.Generic;
public class WeakCollection<T> : Collections.ICollection<T> where T : class
{
private readonly Collections.List<Sys.WeakReference<T>> list = new Collections.List<Sys.WeakReference<T>>();
public void Add( T item ) => list.Add( new Sys.WeakReference<T>( item ) );
public void Clear() => list.Clear();
public int Count => list.Count;
public bool IsReadOnly => false;
Legacy.IEnumerator Legacy.IEnumerable.GetEnumerator() => GetEnumerator();
public bool Contains( T item )
{
foreach( var element in this )
if( Equals( element, item ) )
return true;
return false;
}
public void CopyTo( T[] array, int arrayIndex )
{
foreach( var element in this )
array[arrayIndex++] = element;
}
public bool Remove( T item )
{
for( int i = 0; i < list.Count; i++ )
{
if( !list[i].TryGetTarget( out T target ) )
continue;
if( Equals( target, item ) )
{
list.RemoveAt( i );
return true;
}
}
return false;
}
public Collections.IEnumerator<T> GetEnumerator()
{
for( int i = list.Count - 1; i >= 0; i-- )
{
if( !list[i].TryGetTarget( out T element ) )
{
list.RemoveAt( i );
continue;
}
yield return element;
}
}
}
}
关于c# - 你如何安全地枚举一个 List<Weakreference> 而没有终结器妨碍?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57355009/
当 WeakReference.Target 引用的目标对象被垃圾回收后,WeakReference 会发生什么? WeakRerence 是否存活并保持存在? 我问的原因是我有一个存储在 List
在 .NET 3.5 中,WeakReference 是否与 String 一起工作,还是应该将它包装在一个小的“类”中以使其与它一起工作? 最佳答案 System.String ( string 在
我最近注意到我们的一个应用程序中出现了一种奇怪的行为。 Exception=System.InvalidCastException: Unable to cast object of type 'Sy
我正在开发一个订购系统,这是我的场景:我有一个类以“缓存”策略之类的方式保存新订单。此时,我使用的是这样的HashMap: public static final Map orders = new H
我正在使用 JGroups 作为分布式系统。我想在远程 JVM 上创建对象并像在本地创建一样使用它们。因此,我使用 java.lang.reflect.Proxy 来包装 RPC 调用。这与 RMI
这失败了 public void testWeak() throws Exception { waitGC(); { Sequence a = Sequence.val
考虑下一个 fragment : private void foo() { A a = new A(); WeakReference weakA = new WeakReference
我的静态处理程序对我的 Activity 有一个 WeakReference(这是为了防止记录良好的内存泄漏问题)。 我发布了一条延迟很长时间的消息,我希望将此消息传送到我的 Activity (应该
为什么在下面的程序中调用下面的System.exit(0)?只有本地图引用变量变为空时才应调用它。 import java.lang.ref.WeakReference; import java.ut
我在这里有一个奇怪的行为:我在运行在 DLOG 终端(Windows Embedded Standard SP1)上运行的 WPF 应用程序的生产中出现大量内存泄漏,如果我在普通桌面(Win7 教授)
我有一个缓存,它使用 WeakReferences 来缓存对象,使它们在内存压力的情况下自动从缓存中删除。我的问题是缓存的对象在存储在缓存中后很快就会被收集。缓存在 64 位应用程序中运行,尽管仍
看到篇帖子, 国外一个技术面试官在面试senior java developer的时候, 问到一个weak reference相关的问题. 他没有期望有人能够完整解释清楚weak reference
我们平常用的都是对象的强引用,如果有强引用存在,GC是不会回收对象的。我们能不能同时保持对对象的引用,而又可以让GC需要的时候回收这个对象呢?.NET中提供了WeakReference来实现。弱引用
我明白了什么System.WeakReference确实如此,但我似乎无法理解它可能有用的实际例子。在我看来,这个类(class)本身就是一个黑客。在我看来,还有其他更好的方法来解决我见过的示例中使用
如何自动清除instanceMap的key和value;当 getInstance() API 返回的 Conf 对象是使用 WeakHashMap 和 WeakReference 进行垃圾收集时
我做了一个快速测试来说明我的问题: @Test public void testRemovalFromWakLinkedList() { Object o1 = new Object();
我有另一个 C# 理论问题,我希望我能弄清楚,我已经看到一些 WeakReference 示例,但它们对我不起作用,但我在一些人的评论和文章中读到这些示例对他们有用.我正在努力找出为什么这些样本对我不
假设我有两个 WeakReference 实例,我想看看它们是否指向同一个对象。您可以想象两种场景,一种是两个引用都指向同一个对象: SomeClass a = 1; var wr1 = new We
我知道如果一个对象没有引用,并且 GC 清除了它,该对象的 WeakReference.Target 属性将返回 null, 但是假设这个对象没有强引用,但是GC还没有清除它,有没有办法通过它的弱引用
我知道我应该只对大对象使用 WeakReference,但我对以下场景感到好奇: object obj = 1; //Int32 var wk = new WeakReference(obj);
我是一名优秀的程序员,十分优秀!