@@ -1532,54 +1532,76 @@ export function getTests(
15321532 . didNotThrow ( )
15331533 . equals ( 10_000 )
15341534 ) ,
1535- createTest ( 'HybridObjects dont leak memory' , ( ) =>
1536- it ( ( ) => {
1537- const baselineAllocations =
1538- NitroModules . debug_getTotalAllocatedHybridObjects ( )
1535+ createTest (
1536+ 'HybridObjects dont leak memory with automatic YoungGen GC' ,
1537+ ( ) =>
1538+ it ( ( ) => {
1539+ const baselineAllocations =
1540+ NitroModules . debug_getTotalAllocatedHybridObjects ( )
1541+ const TOTAL_ALLOCATIONS = 10_000
1542+ const BATCH_SIZE = 1000
1543+
1544+ const objects : Array < TestObjectCpp | TestObjectSwiftKotlin > = [ ]
1545+ for ( let i = 0 ; i < TOTAL_ALLOCATIONS ; i ++ ) {
1546+ const object = testObject . newTestObject ( )
1547+ object . numberValue = i
1548+ objects . push ( object )
1549+
1550+ if ( objects . length >= BATCH_SIZE ) {
1551+ objects . length = 0
1552+ gc ( )
1553+ }
1554+ }
1555+
1556+ objects . length = 0
1557+ gc ( )
1558+ gc ( )
1559+ gc ( )
15391560
1561+ const currentAllocations =
1562+ NitroModules . debug_getTotalAllocatedHybridObjects ( )
1563+ const remainingAllocations = currentAllocations - baselineAllocations
1564+ // make sure that less than 10% of the total allocations are remaining, indicating GC ran for most of it.
1565+ const didDeleteMostObjects =
1566+ remainingAllocations < TOTAL_ALLOCATIONS * 0.1
1567+ const result : {
1568+ baselineAllocations : number
1569+ currentAllocations : number
1570+ isEqual ?: boolean
1571+ } = {
1572+ baselineAllocations : baselineAllocations ,
1573+ currentAllocations : currentAllocations ,
1574+ isEqual : didDeleteMostObjects ,
1575+ }
1576+ if ( ! didDeleteMostObjects ) {
1577+ delete result . isEqual
1578+ }
1579+ return result
1580+ } )
1581+ . didNotThrow ( )
1582+ . toContain ( 'isEqual' )
1583+ ) ,
1584+ createTest ( 'HybridObjects dont leak memory with manual dispose()' , ( ) =>
1585+ it ( ( ) => {
1586+ // We test 55_000 allocations, because JNI's max global_ref count
1587+ // is 51200, so if this test goes green, it properly deletes
1588+ // jni::global_refs. If there would be a memory leak, this test
1589+ // will likely crash in C++.
1590+ const TOTAL_ALLOCATIONS = 55_000
15401591 const BATCH_SIZE = 1000
1541- const LOOP_COUNT = 10
1542- const TOTAL_ALLOCATIONS = BATCH_SIZE * LOOP_COUNT
15431592
1544- const objects : Array < TestObjectCpp | TestObjectSwiftKotlin > = [ ]
15451593 for ( let i = 0 ; i < TOTAL_ALLOCATIONS ; i ++ ) {
15461594 const object = testObject . newTestObject ( )
1547- object . numberValue = i
1548- objects . push ( object )
1595+ object . dispose ( )
15491596
1550- if ( objects . length >= BATCH_SIZE ) {
1551- objects . length = 0
1597+ if ( ( i + 1 ) % BATCH_SIZE === 0 ) {
15521598 gc ( )
15531599 }
15541600 }
15551601
1556- objects . length = 0
15571602 gc ( )
1558- gc ( )
1559- gc ( )
1560-
1561- const currentAllocations =
1562- NitroModules . debug_getTotalAllocatedHybridObjects ( )
1563- const remainingAllocations = currentAllocations - baselineAllocations
1564- // make sure that less than 10% of the total allocations are remaining, indicating GC ran for most of it.
1565- const didDeleteMostObjects =
1566- remainingAllocations < TOTAL_ALLOCATIONS * 0.1
1567- const result : {
1568- baselineAllocations : number
1569- currentAllocations : number
1570- isEqual ?: boolean
1571- } = {
1572- baselineAllocations : baselineAllocations ,
1573- currentAllocations : currentAllocations ,
1574- isEqual : didDeleteMostObjects ,
1575- }
1576- if ( ! didDeleteMostObjects ) {
1577- delete result . isEqual
1578- }
1579- return result
1580- } )
1581- . didNotThrow ( )
1582- . toContain ( 'isEqual' )
1603+ return TOTAL_ALLOCATIONS
1604+ } ) . didNotThrow ( )
15831605 ) ,
15841606 createTest ( 'callWithOptional(undefined)' , async ( ) =>
15851607 (
0 commit comments