Project

General

Profile

Bug #11164 ยป memory_test_min.rb

tkalmus (Thomas Kalmus), 05/20/2015 03:04 PM

 
1
$start_time=Time.new
2

    
3
# Monitor use of Resident and Virtual memory.
4
class Memory
5

    
6
    shared_dirty = '.+?Shared_Dirty:\s+(\d+)'
7
    priv_dirty = '.+?Private_Dirty:\s+(\d+)'
8
    MEM_REGEXP = /#{shared_dirty}#{priv_dirty}/m
9

    
10
	# get memory usage
11
    def self.get_memory_map( pids)
12
        memory_map = {}
13
        memory_map[ :pids_found] = {}
14
        memory_map[ :shared_dirty] = 0
15
        memory_map[ :priv_dirty] = 0
16

    
17
        pids.each do |pid|
18
            begin
19
                lines = nil
20
                lines = File.read( "/proc/#{pid}/smaps")
21
            rescue
22
                lines = nil
23
            end
24
            if lines
25
                lines.scan(MEM_REGEXP) do |shared_dirty, priv_dirty|
26
                    memory_map[ :pids_found][pid] = true
27
                    memory_map[ :shared_dirty] += shared_dirty.to_i
28
                    memory_map[ :priv_dirty] += priv_dirty.to_i
29
                end
30
            end
31
        end
32
        memory_map[ :pids_found] = memory_map[ :pids_found].keys
33
        return memory_map
34
    end
35

    
36
	# get the processes and get the value of the memory usage
37
    def self.memory_usage( )
38
		pids   = [ $$]
39
		result = self.get_memory_map( pids)
40

    
41
        result[ :pids]   = pids
42
        return result
43
    end
44

    
45
	# print the values of the private and shared memories
46
    def self.log( process_name='', log_tag="")
47
        if process_name == "header"
48
            puts " %-6s %5s %-12s %10s %10s\n" % ["proces", "pid", "log", "priv_dirty", "shared_dirty"]
49
        else
50
            time = Time.new - $start_time
51
            mem = Memory.memory_usage( )
52
            puts " %-6s %5d %-12s %10d %10d\n" % [process_name, $$, log_tag, mem[:priv_dirty]/1000, mem[:shared_dirty]/1000]
53
        end
54
    end
55
end
56

    
57
# function to delay the processes a bit
58
def time_step( n)
59
    while Time.new - $start_time < n
60
        sleep( 0.01)
61
    end
62
end
63

    
64
# create an object of specified size. The option argument can be changed from 0 to 2 to visualize the behavior of the GC in various cases
65
#
66
# case 0 (default) : we make a huge array of small objects by formatting a string
67
# case 1 : we make a huge array of small objects without formatting a string (we use the to_s function)
68
# case 2 : we make a smaller array of big objects
69
def memory_object( size, option=0)
70
    result = []
71
    count = size/20
72
    
73
    if option > 3 or option < 1
74
		count.times do
75
			result << "%20.18f" % rand
76
		end
77
    elsif option == 1
78
		count.times do
79
			result << rand.to_s
80
		end
81
	elsif option == 2
82
		count = count/10
83
		count.times do
84
			result << ("%20.18f" % rand)*30
85
		end
86
	end
87
    
88
    return result
89
end
90

    
91
##### main #####
92

    
93
puts "ruby version #{RUBY_VERSION}"
94

    
95
GC.disable
96

    
97
# print the column headers and first line
98
Memory.log( "header")
99

    
100
# Allocation of memory
101
big_memory = memory_object( 1000 * 1000 * 10)
102

    
103
Memory.log( "Parent", "post alloc")
104

    
105
lab_time = Time.new - $start_time
106
if lab_time < 3.9
107
    lab_time = 0
108
end
109

    
110
# start the forking
111
pid = fork do
112
    time = 4
113
    time_step( time + lab_time)
114
    Memory.log( "Child", "#{time} initial")
115

    
116
	# force GC when nothing happened
117
	GC.enable; GC.start; GC.disable
118

    
119
    time = 8
120
    time_step( time + lab_time)
121
    Memory.log( "Child", "#{time} empty GC")
122

    
123
    sleep( 1)
124
    STDOUT.flush
125
    exit!
126
end
127

    
128
time = 4
129
time_step( time + lab_time)
130
Memory.log( "Parent", "#{time} fork")
131

    
132
# wait for the child to finish
133
Process.wait( pid)
134