由于压缩垃圾回收,调用以报告堆中对象的新布局。 如果探查器已实现 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 回调指示所有对象都已移动到其新位置,并且可以执行检查。
如果探查器同时实现 ICorProfilerCallback 和 ICorProfilerCallback4 接口,则 MovedReferences2 该方法在 ICorProfilerCallback::MovedReferences 方法之前调用,但前提是 MovedReferences2 该方法成功返回。 探查器可以返回指示方法失败的 MovedReferences2 HRESULT,以避免调用第二种方法。
要求
平台:请参阅系统要求。
页眉: CorProf.idl、CorProf.h
图书馆: CorGuids.lib
.NET Framework 版本: 自 4.5 起可用