Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/351.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
Java JVM-是否在次要GC中收集WeakReference?_Java_Garbage Collection_Jvm_Weak References - Fatal编程技术网

Java JVM-是否在次要GC中收集WeakReference?

Java JVM-是否在次要GC中收集WeakReference?,java,garbage-collection,jvm,weak-references,Java,Garbage Collection,Jvm,Weak References,我想知道这一点,因为这会使它们变得不那么有用。如果是这样的话,有没有一种方法可以使主GC上的内存只被弱引用为“垃圾” 你为什么要这样?您的程序不应该太在意主GC周期和次GC周期,事实上,这种区别甚至不会存在于所有JVM/GC配置中 WeakReferences可在没有对对象的强引用时立即收集。这可能包括小型地面军事系统 如果您想让对象停留一段时间,直到出现实际内存压力,请尝试。javadoc没有明确说明清除/中断WeakReference的“时间尺度”。这将使你的问题的答案(至少在理论上)“它取

我想知道这一点,因为这会使它们变得不那么有用。如果是这样的话,有没有一种方法可以使主GC上的内存只被弱引用为“垃圾”

你为什么要这样?您的程序不应该太在意主GC周期和次GC周期,事实上,这种区别甚至不会存在于所有JVM/GC配置中

WeakReference
s可在没有对对象的强引用时立即收集。这可能包括小型地面军事系统


如果您想让对象停留一段时间,直到出现实际内存压力,请尝试。

javadoc没有明确说明清除/中断
WeakReference的“时间尺度”。这将使你的问题的答案(至少在理论上)“它取决于实现”。事实上,JLS规范和javadocs甚至没有提到主要集合和次要集合。整个主题属于“实现细节”类别

如果您确实需要对GC敏感的引用,那么您可能应该使用一个。其描述如下:

“在虚拟机抛出OutOfMemoryError之前,保证已清除对软访问对象的所有软引用。否则,不会对清除软引用的时间或清除对不同对象的一组此类引用的顺序设置任何约束。但是,鼓励虚拟机实现偏向于清除最近创建或使用的软引用。”

在其他地方,软引用被描述为强于弱引用。这意味着它不太可能被破坏;例如,被过于急切的垃圾收集器破坏。但请注意,这些都没有涉及主要垃圾收集与次要垃圾收集


更新我在Java 11源代码树中研究了以下(非常合理的!)声明:

次要收集将收集年轻空间中的任何对象。对年轻空间中对象的
WeakReference
将在次要GC上收集

本机引用处理代码很复杂。有一个通用的
ReferenceProcessor
类执行以下操作:

  • 它选择性地记录GC遇到的
    Reference
    对象。GC代码调用
    ReferenceProcessor::discover\u Reference
    来实现这一点
  • 它迭代发现的
    引用
    对象,以确定是否中断引用。相关的
    引用
    对象将添加到各自的引用队列中
并发症如下:

  • GC可以调用也可以不调用
    ReferenceProcessor::discover\u reference
    。据我所知,大多数(如果不是全部)GC都会调用它,但很难确定

  • ReferenceProcessor
    具有不同的策略,用于处理引用和引用对象处于不同代(或跨代)的情况。(如果不处理引用,则引用对象将被视为当前集合难以访问。)

简言之,我可以确认
Reference
对象通常将在小型GC中处理。但是,特定
Reference
的实际行为可能取决于生成/span问题

(应该可以从GC日志中观察特定GC的一般行为。查找引用处理阶段的统计或计时。)



1-注释中使用了“跨度”一词。我认为它与将旧一代划分为多个区域(跨度)的收集器(如G1)有关它们分别收集。

这将取决于WeakReference对象是否在Eden中-次要收集将只查看Eden中的对象。

您可能会想到更接近您所需的软引用


次要收集将收集年轻空间中的任何对象。对年轻空间中对象的WeakReference将在次要GC上收集。对终身空间中对象的WeakReference将在终身收集上收集,例如Full GC。顺便说一句,您只能同时收集终身空间。

WeakReference
不会阻止对象的收集,所以如果对象属于年轻空间,并且只能通过弱引用访问,则将收集该对象

SoftReferences
(在热点JVM中)根据上次访问时间戳(上次调用
get()
的时间戳)充当弱引用或强引用。sotf引用的“到期时间”计算为可用内存大小乘以通过
-XX:SoftRefLRUPolicyMSPerMB=T配置的系数(例如,可用内存较少,软引用的有效期较短)

通常,使用JVM引用进行缓存不是一个好主意: -它将临时对象提升到旧空间,打破了弱世代假设 -通过GC增加次要GC时间,引用以特殊方式受到威胁


如果您需要具有逐出策略的缓存,最好显式地实现它,并在逐出策略中考虑影响存储数据的内存占用。

Brian Goetz(2006年的文章)的一些见解似乎仍在viguor中:


->[穷人的缓存]和[垃圾收集器如何处理引用]中有趣的细节段落。

伊甸园中的对象在进入终身世代之前必须在一些小集合中存活下来,因此您的回答不会让唤醒认为您指的是年轻空间,即伊甸园和幸存者空间,由小集合收集。您不能否认这是一个值得了解的细节。例如,在实现缓存或有些东西。@PabloFernandez:我不同意。如果你依赖于了解缓存的实现细节,那么当有人升级JVM时,缓存就会崩溃,这将是一个巨大的痛苦