1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
|
# coding: utf-8
assert('ObjectSpace.count_objects') do
h = {}
f = Fiber.new {} if Object.const_defined?(:Fiber)
ObjectSpace.count_objects(h)
assert_kind_of(Hash, h)
assert_true(h.keys.all? {|x| x.is_a?(Symbol) || x.is_a?(Integer) })
assert_true(h.values.all? {|x| x.is_a?(Integer) })
assert_true(h.has_key?(:TOTAL))
assert_true(h.has_key?(:FREE))
assert_true(h.has_key?(:T_FIBER)) if Object.const_defined? :Fiber
assert_equal(h[:TOTAL] * 2, h.values.reduce(:+))
h = ObjectSpace.count_objects
assert_kind_of(Hash, h)
assert_true(h.keys.all? {|x| x.is_a?(Symbol) || x.is_a?(Integer) })
assert_true(h.values.all? {|x| x.is_a?(Integer) })
assert_raise(TypeError) { ObjectSpace.count_objects(1) }
h0 = {:T_FOO=>1000}
h = ObjectSpace.count_objects(h0)
assert_false(h0.has_key?(:T_FOO))
GC.start
h_after = {}
h_before = ObjectSpace.count_objects
objs = []
1000.times do
objs << {}
end
ObjectSpace.count_objects(h)
objs = nil
GC.start
ObjectSpace.count_objects(h_after)
assert_equal(h[:T_HASH], h_before[:T_HASH] + 1000)
assert_equal(h_after[:T_HASH], h_before[:T_HASH])
end
assert('ObjectSpace.each_object') do
objs = []
objs_count = ObjectSpace.each_object { |obj|
objs << obj
}
assert_equal objs.length, objs_count
arys = []
arys_count = ObjectSpace.each_object(Array) { |obj|
arys << obj
}
assert_equal arys.length, arys_count
assert_true arys.length < objs.length
end
assert 'Check class pointer of ObjectSpace.each_object.' do
assert_nothing_raised { ObjectSpace.each_object { |obj| !obj } }
end
assert 'ObjectSpace.memsize_of' do
# immediate literals
int_size = ObjectSpace.memsize_of 1
assert_equal int_size, 0, 'int zero'
sym_size = ObjectSpace.memsize_of :foo
assert_equal sym_size, 0, 'sym zero'
assert_equal ObjectSpace.memsize_of(true), int_size
assert_equal ObjectSpace.memsize_of(false), int_size
float_size = if Object.const_defined? :Float
ObjectSpace.memsize_of 1.0
else
nil
end
# need some way of asking if floats are boxed
assert_equal float_size, 0 if float_size
assert_not_equal ObjectSpace.memsize_of('a'), 0, 'memsize of str'
if __ENCODING__ == "UTF-8"
assert_not_equal ObjectSpace.memsize_of("こんにちは世界"), 0, 'memsize of utf8 str'
end
assert_not_equal ObjectSpace.memsize_of(0..1), 0, 'range not zero'
# class defs
class_obj_size = ObjectSpace.memsize_of Class
assert_not_equal class_obj_size, 0, 'Class obj not zero'
empty_class_def_size = ObjectSpace.memsize_of Class.new
assert_not_equal empty_class_def_size, 0, 'Class def not zero'
class_without_methods = Class.new do
@a = 1
@b = 2
end
class_total_size = empty_class_def_size + (int_size * 2)
assert_equal ObjectSpace.memsize_of(class_without_methods), class_total_size, 'class without methods size'
module_without_methods = Module.new do
@a = 1
@b = 2
end
module_total_size = empty_class_def_size + (int_size * 2)
assert_equal ObjectSpace.memsize_of(module_without_methods), module_total_size, 'module without methods size'
proc_size = ObjectSpace.memsize_of Proc.new { x = 1; x }
assert_not_equal proc_size, 0
class_with_methods = Class.new do
def foo
a = 0
a + 1
end
end
m_size = ObjectSpace.memsize_of class_with_methods.instance_method(:foo)
assert_not_equal m_size, 0, 'method size not zero'
# collections
empty_array_size = ObjectSpace.memsize_of []
assert_not_equal empty_array_size, 0, 'empty array size not zero'
assert_operator empty_array_size, :<, ObjectSpace.memsize_of(Array.new(16)), 'large array size greater than embed'
# fiber
empty_fiber_size = ObjectSpace.memsize_of(Fiber.new {})
assert_not_equal empty_fiber_size, 0, 'empty fiber not zero'
assert_operator empty_fiber_size, :<, ObjectSpace.memsize_of(Fiber.new { yield; 1 }), 'Fiber code size growth'
#hash
assert_not_equal ObjectSpace.memsize_of({}), 0, 'empty hash size not zero'
# recursion
foo_str = 'foo' * 10
bar_str = 'bar' * 10
caz_str = 'caz' * 10
fbc_ary = [foo_str, bar_str, caz_str]
assert_operator ObjectSpace.memsize_of(fbc_ary),
:<,
ObjectSpace.memsize_of(fbc_ary, recurse: true),
'basic array recursion'
big_ary = [ 'a' * 10,
[ 'b' * 10,
[ 'c' * 10,
[ 'd' * 10,
[ 'e' * 10,
[ 'f' * 10,
['g' * 10]
] * 10,
] * 10,
] * 10,
] * 10,
] * 10,
] * 10
assert_operator ObjectSpace.memsize_of(big_ary),
:<,
ObjectSpace.memsize_of(big_ary, recurse: true),
'large array recursion'
assert_nothing_raised 'infinite array recursion' do
ObjectSpace.memsize_of(fbc_ary.push(fbc_ary))
end
basic_hsh = {a: [foo_str, bar_str], b: caz_str, 'c' => {}}
assert_operator ObjectSpace.memsize_of(basic_hsh),
:<,
ObjectSpace.memsize_of(basic_hsh, recurse: true),
'hash recursion with basic keys'
weird_keys = {big_ary => foo_str}
assert_operator ObjectSpace.memsize_of(weird_keys),
:<,
ObjectSpace.memsize_of(weird_keys, recurse: true),
'hash recursion with collection as key'
basic_hsh.store('d', basic_hsh)
assert_nothing_raised 'hash value recursion' do
ObjectSpace.memsize_of basic_hsh, recurse: true
end
foo_klass = Class.new do
def bar= b
@bar = b
end
end
fk_one = foo_klass.new
fk_one.bar = fbc_ary
assert_operator ObjectSpace.memsize_of(fk_one),
:<,
ObjectSpace.memsize_of(fk_one, recurse: true),
'basic ivar recursion'
fk_one.bar = fk_one
assert_nothing_raised 'ivar infinite recursion' do
ObjectSpace.memsize_of(fk_one, recurse: true)
end
end
|