If an expectation fails and hits an unreachable() instruction, any unreleased references in the function call stack will be held indefinitely as a memory leak. Test Suites don't stop running if they fail the test callback. However, tests will stop if they fail inside the beforeEach(), beforeAll(), afterEach(), and afterAll() callbacks.
Typically, a throws() test will leave at least a single Expectation on the heap. This is to be expected, because the unreachable() instruction unwinds the stack, and prevents the ability for each function to __release a reference pointer properly. Your test suite output may look like this:
[Describe]: toHaveLength TypedArray type: Uint32Array
[Success]: โ should assert expected length
[Throws]: โ when expected length should not equal the same value RTrace: +3
[Success]: โ should verify the length is not another value
[Throws]: โ when the length is another expected value RTrace: +3
The RTrace: +3 corresponds to an Expectation, a Uint32Array, and a single backing ArrayBuffer that was left on the heap because of the fact that the expectation failed. This was expected because these two tests were annotated with the throws(desc, callback) function. If you see a function that is expected to pass and RTrace returns a very large value, it might be an indicator of a very serious memory leak, and the DefaultTestReporter can be your best friend when it comes to finding these sorts of problems.
Among other solutions, the following methods are exposed to you as a way to inspect how many allocations and frees occurred during the course of function execution.
declareclassRTrace {/** Return the current number of active references on the heap. */publicstaticcount():i32;/** * Start counting heap allocations. * * @param{i32} label - The numeric label for this refcounting group. */publicstaticstart(label:i32):void;/** * End counting heap allocations. * * @param{i32} label - The numeric label for this refcounting group. * @returns The delta number of heap allocations relative to the start. */publicstaticend(label:i32):i32;/** Overall module count for ARC increments. */publicstaticincrements():i32;/** Overall module count for ARC decrements. */publicstaticdecrements():i32;/** Overall TestGroup count for ARC increments. */publicstaticgroupIncrements():i32;/** Overall TestGroup count for ARC decrements. */publicstaticgroupDecrements():i32;/** Overall Test count for ARC increments. */publicstatictestIncrements():i32;/** Overall Test count for ARC decrements. */publicstatictestDecrements():i32;/** Overall count for ARC allocations. */publicstaticallocations():i32;/** Overall count for ARC frees. */publicstaticfrees():i32;/** TestGroup count for ARC allocations. */publicstaticgroupAllocations():i32;/** TestGroup count for ARC frees. */publicstaticgroupFrees():i32;/** Test count for ARC allocations. */publicstatictestAllocations():i32;/** Test count for ARC frees. */publicstatictestFrees():i32;/** Overall count for ARC reallocations. */publicstaticreallocations():i32;/** TestGroup count for ARC reallocations. */publicstaticgroupReallocations():i32;/** TestGroup count for ARC reallocations. */publicstatictestReallocations():i32;/** * This method triggers a garbage collection. */publicstaticcollect():void;/** * Get the type id (class id) of the pointer. * * @param{usize} pointer - The pointer. * @returns{u32} - The type id of the allocated block. */publicstatictypeIdOf(pointer:usize):u32;/** * Get the type id (class id) of a reference. * * @param{T} reference - The reference. * @returns{u32} - The type id of the allocated block. */publicstatictypeIdOfReference<T>(reference:T):u32;/** * Get the size of a pointer. * * @param{usize} pointer - The pointer. * @returns{u32} - The size of the allocated block. */publicstaticsizeOf(pointer:usize):u32;/** * Get the size of a reference. * * @param{T} reference - The reference. * @returns{u32} - The size of the allocated block. */publicstaticsizeOfReference<T>(reference:T):u32;/** * Get the currently allocated blocks. */publicstaticactiveBlocks():usize[];/** * Get the current groups allocated blocks. */publicstaticactiveGroupBlocks():usize[];/** Get the current tests allocated blocks. */publicstaticactiveTestBlocks():usize[];/** Get the current ARC count of a given pointer. */publicstaticrefCountOf(ptr:usize):u32;/** * Gets the current count of the specified reference. * @param{T} reference - the reference. */publicstaticrefCountOfReference<T>(reference:T):u32;}
Every one of these functions exist in the RTrace namespace and will call into JavaScript to query the state of the heap relative to the overall test file, the test group, and each individual test depending on the function.
RTrace can be disabled with the --nortrace cli option, to avoid collecting reference counting statistics.