Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#弱引用实际上是软引用吗?_C#_.net_Garbage Collection_Weak References_Soft References - Fatal编程技术网

C#弱引用实际上是软引用吗?

C#弱引用实际上是软引用吗?,c#,.net,garbage-collection,weak-references,soft-references,C#,.net,Garbage Collection,Weak References,Soft References,基本区别在于,弱引用应该在每次GC运行时声明(保持内存占用率较低),而软引用应该保留在内存中,直到GC实际需要内存为止(它们尝试扩展生存期,但可能随时失败,这对于缓存,尤其是对于相当昂贵的对象,非常有用) 据我所知,关于弱引用如何影响.NET中对象的生存期,还没有明确的说法。如果它们是真正的弱引用,它们不应该影响它,但这也会使它们在缓存的主要目的(我错了吗?)方面变得毫无用处。另一方面,如果他们表现得像软裁判,他们的名字就有点误导 就我个人而言,我认为它们的行为就像软引用,但这只是一种印象,没有

基本区别在于,弱引用应该在每次GC运行时声明(保持内存占用率较低),而软引用应该保留在内存中,直到GC实际需要内存为止(它们尝试扩展生存期,但可能随时失败,这对于缓存,尤其是对于相当昂贵的对象,非常有用)

据我所知,关于弱引用如何影响.NET中对象的生存期,还没有明确的说法。如果它们是真正的弱引用,它们不应该影响它,但这也会使它们在缓存的主要目的(我错了吗?)方面变得毫无用处。另一方面,如果他们表现得像软裁判,他们的名字就有点误导

就我个人而言,我认为它们的行为就像软引用,但这只是一种印象,没有根据

实施细节当然适用。我想问的是与.NET弱引用相关的心态——它们是否能够延长生命周期,还是表现得像真正的弱引用

(尽管有许多相关的问题,我仍然找不到这个具体问题的答案。)



弱引用不会延长对象的生命周期,因此允许在所有强引用都超出范围后对其进行垃圾收集。它们可以用于保存大型对象,这些对象的初始化成本很高,但如果它们不在使用中,则应可用于garabage收集。

我没有看到任何信息表明它们会延长它们指向的对象的生存期。我读到的关于GC用来确定可达性的算法的文章也没有以这种方式提到它们。所以我希望它们对物体的寿命没有影响


此句柄类型用于跟踪对象,但允许收集对象。收集对象时,GCHandle的内容将归零。弱引用在终结器运行之前归零,因此即使终结器重新恢复对象,弱引用仍然归零

WeakTrack复活
此句柄类型类似于“弱”,但如果在终结过程中恢复对象,则句柄不会置零


有几种机制可以使无法访问的对象在垃圾收集中幸存下来

  • 对象的生成大于发生的GC的生成。这对于大型对象来说尤其有趣,因为大型对象是在大型对象堆上分配的,因此通常被认为是Gen2
  • 具有终结器的对象以及所有可从它们访问的对象在GC中仍然有效
  • 也许有一种机制可以让来自旧对象的前引用保持年轻对象的活力,但我不确定这一点
C#弱引用实际上是软引用吗

没有

我错了吗

你错了。弱引用的目的绝对不是您所指的缓存。这是一个常见的误解

它们是否能够延长寿命,或者它们的行为是否像真正的弱引用

不,它们不会延长寿命

考虑以下程序(F代码):

此堆分配一个可立即进行垃圾收集的空数组。然后我们循环10万次,分配更多无法访问的数组。请注意,这根本不会增加内存压力,因此没有动机收集弱引用引用的数组。然而,该程序打印“弱引用已死亡”,因为它是收集的。这是弱引用的行为。软引用将一直保留到实际需要它的内存为止

下面是另一个测试程序(F代码):

开放系统
让我活着(x:WeakReference)=x.isAlive
做
设可变xs=[]
尽管如此

xs我从来没有听说过,除了调用GC.Collect()之外,您可以对GC回收对象的确切时间施加任何影响。从这个角度来看,Weakreference声明的唯一一件事就是对象是可回收的。@flq:例如,在Java中,通过选择一个软引用或弱引用是可能的。软引用的基本意思是“我不介意这个被声明,但请试着保留它”。您是否将Java范例应用于C#,在C#中,通常弱引用只是对GC可以随时收集的内容的引用。@BenRobinson:应该仍然可以区分。除非他们明确地想在这个问题上保持模棱两可(这是完全可能的)。@CodeInChaos:我从迄今为止我读到的关于这个话题的资料中得到了这个印象,尤其是MSDN。这些例子倾向于展示一些场景,在这些场景中,软性行为而非弱性行为更可取。让我在这里试着准确地说,它们是否试图延长寿命?如果你可以链接到一个源进行进一步阅读,那就太好了。哦,他们只是不知道是否要gc一个对象——他们不做决定,他们只是不让一个对象保持活动状态。进一步阅读后,这似乎是正确的答案。我仍然找不到一个明确声明“不会以任何方式影响寿命”的来源。关于“弱”与“弱追踪复活”的描述是模糊的,也不是真正准确的。一旦对象符合立即完成的条件,弱句柄将被清除;WeakTrackResurvation句柄将保持有效,直到对象停止存在或句柄的所有者使其无效。不幸的是,当一个
WeakReference
被要求创建一个
weaktrackresurvation
句柄时,除非对
WeakReference
本身存在一个强根引用,否则它很容易过早地对其进行核攻击。我不确定我是否能遵循。我没有说弱引用应该用于缓存,但是软引用应该(我想你也是这么说的)。MSDN声明“C弱”
do
  let x = System.WeakReference(Array.create 0 0)
  for i=1 to 10000000 do
    ignore(Array.create 0 0)
  if x.IsAlive then "alive" else "dead"
  |> printfn "Weak reference is %s"
open System

let isAlive (x: WeakReference) = x.IsAlive

do
  let mutable xs = []
  while true do
    xs <- WeakReference(Array.create 0 0)::List.filter isAlive xs
    printfn "%d" xs.Length