Skip to content

Commit bc30d34

Browse files
committed
Add incemental GC stress test
1 parent 6d4e9f8 commit bc30d34

File tree

1 file changed

+48
-0
lines changed

1 file changed

+48
-0
lines changed

Lib/test/test_gc.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1058,6 +1058,54 @@ class Z:
10581058
callback.assert_not_called()
10591059
gc.enable()
10601060

1061+
def test_incremental_gc_handles_fast_cycle_creation(self):
1062+
1063+
class LinkedList:
1064+
1065+
#Use slots to reduce number of implicit objects
1066+
__slots__ = "next", "prev", "surprise"
1067+
1068+
def __init__(self, next=None, prev=None):
1069+
self.next = next
1070+
if next is not None:
1071+
next.prev = self
1072+
self.prev = prev
1073+
if prev is not None:
1074+
prev.next = self
1075+
1076+
def make_ll(depth):
1077+
head = LinkedList()
1078+
for i in range(depth):
1079+
head = LinkedList(head, head.prev)
1080+
return head
1081+
1082+
head = make_ll(10000)
1083+
count = 10000
1084+
1085+
# We expect the counts to go negative eventually
1086+
# as there will some objects we aren't counting,
1087+
# e.g. the gc stats dicts. The test merely checks
1088+
# that the counts don't grow.
1089+
1090+
enabled = gc.isenabled()
1091+
gc.enable()
1092+
olds = []
1093+
for i in range(1000):
1094+
newhead = make_ll(200)
1095+
count += 200
1096+
newhead.surprise = head
1097+
olds.append(newhead)
1098+
if len(olds) == 50:
1099+
stats = gc.get_stats()
1100+
young = stats[0]
1101+
incremental = stats[1]
1102+
old = stats[2]
1103+
collected = young['collected'] + incremental['collected'] + old['collected']
1104+
live = count - collected
1105+
self.assertLess(live, 25000)
1106+
del olds[:]
1107+
if not enabled:
1108+
gc.disable()
10611109

10621110
class GCCallbackTests(unittest.TestCase):
10631111
def setUp(self):

0 commit comments

Comments
 (0)