ICorProfilerCallback4::MovedReferences2 方法

由于压缩垃圾回收,调用以报告堆中对象的新布局。 如果探查器已实现 ICorProfilerCallback4 接口,则调用此方法。 此回调将替换 ICorProfilerCallback::MovedReferences 方法,因为它可以报告其长度超过 ULONG 中可以表示的内容的更大范围的对象。

Syntax

HRESULT MovedReferences2(
    [in]  ULONG  cMovedObjectIDRanges,
    [in, size_is(cMovedObjectIDRanges)] ObjectID oldObjectIDRangeStart[] ,
    [in, size_is(cMovedObjectIDRanges)] ObjectID newObjectIDRangeStart[] ,
    [in, size_is(cMovedObjectIDRanges)] SIZE_T    cObjectIDRangeLength[] );

参数

cMovedObjectIDRanges [in]由于压缩垃圾回收而移动的连续对象的块数。 也就是说,该值cMovedObjectIDRanges是和newObjectIDRangeStartcObjectIDRangeLength数组的总大小oldObjectIDRangeStart

接下来的三个参数 MovedReferences2 是并行数组。 换句话说,oldObjectIDRangeStart[i]newObjectIDRangeStart[i]所有cObjectIDRangeLength[i]对象都涉及一个连续对象的块。

oldObjectIDRangeStart [in]一个 ObjectID 值数组,每个值都是旧(前垃圾回收)开始地址的内存中连续实时对象块的地址。

newObjectIDRangeStart [in]一个 ObjectID 值数组,每个值都是新的(垃圾回收后)起始地址,即内存中连续的实时对象块的地址。

cObjectIDRangeLength [in]整数数组,每个数组都是内存中连续对象的块的大小。

为在数组中oldObjectIDRangeStartnewObjectIDRangeStart引用的每个块指定大小。

注解

压缩垃圾回收器回收死对象占用的内存,并压缩释放空间的内存。 因此,实时对象可能在堆中移动,并且 ObjectID 以前通知分发的值可能会更改。

假设现有 ObjectID 值 (oldObjectID) 位于以下范围内:

oldObjectIDRangeStart[i] <= oldObjectID<oldObjectIDRangeStart[i] + cObjectIDRangeLength[i]

在这种情况下,从范围开始到对象的起始位置的偏移量如下所示:

oldObjectID - oldObjectRangeStart[i]

对于以下范围内的任何值 i

0 <= i<cMovedObjectIDRanges

可以按如下方式计算新 ObjectID 项:

newObjectID = newObjectIDRangeStart[i] + (oldObjectID - oldObjectIDRangeStart[i]

在回调本身期间,传递MovedReferences2的值ObjectID都不有效,因为垃圾回收器可能在将对象从旧位置移动到新位置的过程中。 因此,探查器不应尝试在调用期间 MovedReferences2 检查对象。 ICorProfilerCallback2::GarbageCollectionFinished 回调指示所有对象都已移动到其新位置,并且可以执行检查。

如果探查器同时实现 ICorProfilerCallbackICorProfilerCallback4 接口,则 MovedReferences2 该方法在 ICorProfilerCallback::MovedReferences 方法之前调用,但前提是 MovedReferences2 该方法成功返回。 探查器可以返回指示方法失败的 MovedReferences2 HRESULT,以避免调用第二种方法。

要求

平台:请参阅系统要求

页眉: CorProf.idl、CorProf.h

图书馆: CorGuids.lib

.NET Framework 版本: 自 4.5 起可用

另请参阅