memory-leak 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/lib/memory/leak/cluster.rb +30 -17
- data/lib/memory/leak/monitor.rb +28 -11
- data/lib/memory/leak/version.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +2 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 426ae960c62375c639420dcf7f498e9e5226b1519614b1fff452b2212f70d7fe
|
4
|
+
data.tar.gz: 6002732a1fb1e17fc105ca6528a510e3d0f564827ff7197682286e68f98a0da9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f36940083fb9907c227bff8242af9ec35a64951f9621b8581adce24cfbb8b2510c7810415d04125e201b36838a06775d9204a6dfc953c780134dec2115924f6d
|
7
|
+
data.tar.gz: 4e727229e8b12a4c73b88066c423f4683a3e9b21fe29c42214eab422c6e310463dc71152c539d5f6cd302e08b9f0ecc3e7166e7620d031c543d90483a3f7e134
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/lib/memory/leak/cluster.rb
CHANGED
@@ -18,42 +18,55 @@ module Memory
|
|
18
18
|
def initialize(limit: nil)
|
19
19
|
@limit = limit
|
20
20
|
|
21
|
-
@
|
21
|
+
@processes = {}
|
22
|
+
end
|
23
|
+
|
24
|
+
# @returns [Hash] A serializable representation of the cluster.
|
25
|
+
def as_json(...)
|
26
|
+
{
|
27
|
+
limit: @limit,
|
28
|
+
processes: @processes.transform_values(&:as_json),
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
# @returns [String] The JSON representation of the cluster.
|
33
|
+
def to_json(...)
|
34
|
+
as_json.to_json(...)
|
22
35
|
end
|
23
36
|
|
24
37
|
# @attribute [Numeric | Nil] The memory limit for the cluster.
|
25
38
|
attr_accessor :limit
|
26
39
|
|
27
|
-
# @attribute [Hash(
|
28
|
-
attr :
|
40
|
+
# @attribute [Hash(Integer, Monitor)] The process IDs and monitors in the cluster.
|
41
|
+
attr :processes
|
29
42
|
|
30
43
|
# Add a new process ID to the cluster.
|
31
|
-
def add(
|
32
|
-
@
|
44
|
+
def add(process_id, **options)
|
45
|
+
@processes[process_id] = Monitor.new(process_id, **options)
|
33
46
|
end
|
34
47
|
|
35
48
|
# Remove a process ID from the cluster.
|
36
|
-
def remove(
|
37
|
-
@
|
49
|
+
def remove(process_id)
|
50
|
+
@processes.delete(process_id)
|
38
51
|
end
|
39
52
|
|
40
|
-
# Apply the memory limit to the cluster. If the total memory usage exceeds the limit, yields each
|
53
|
+
# Apply the memory limit to the cluster. If the total memory usage exceeds the limit, yields each process ID and monitor in order of maximum memory usage, so that they could be terminated and/or removed.
|
41
54
|
#
|
42
|
-
# @yields {|
|
55
|
+
# @yields {|process_id, monitor| ...} each process ID and monitor in order of maximum memory usage, return true if it was terminated to adjust memory usage.
|
43
56
|
def apply_limit!(limit = @limit)
|
44
|
-
total = @
|
57
|
+
total = @processes.values.map(&:current).sum
|
45
58
|
|
46
59
|
if total > limit
|
47
60
|
Console.warn(self, "Total memory usage exceeded limit.", total: total, limit: limit)
|
48
61
|
end
|
49
62
|
|
50
|
-
sorted = @
|
63
|
+
sorted = @processes.sort_by do |process_id, monitor|
|
51
64
|
-monitor.current
|
52
65
|
end
|
53
66
|
|
54
|
-
sorted.each do |
|
67
|
+
sorted.each do |process_id, monitor|
|
55
68
|
if total > limit
|
56
|
-
if yield
|
69
|
+
if yield process_id, monitor, total
|
57
70
|
total -= monitor.current
|
58
71
|
end
|
59
72
|
else
|
@@ -64,17 +77,17 @@ module Memory
|
|
64
77
|
|
65
78
|
# Check all processes in the cluster for memory leaks.
|
66
79
|
#
|
67
|
-
# @yields {|
|
80
|
+
# @yields {|process_id, monitor| ...} each process ID and monitor that is leaking or exceeds the memory limit.
|
68
81
|
def check!(&block)
|
69
82
|
leaking = []
|
70
83
|
|
71
|
-
@
|
84
|
+
@processes.each do |process_id, monitor|
|
72
85
|
monitor.sample!
|
73
86
|
|
74
87
|
if monitor.leaking?
|
75
|
-
Console.debug(self, "Memory Leak Detected!",
|
88
|
+
Console.debug(self, "Memory Leak Detected!", process_id: process_id, monitor: monitor)
|
76
89
|
|
77
|
-
leaking << [
|
90
|
+
leaking << [process_id, monitor]
|
78
91
|
end
|
79
92
|
end
|
80
93
|
|
data/lib/memory/leak/monitor.rb
CHANGED
@@ -13,9 +13,9 @@ module Memory
|
|
13
13
|
#
|
14
14
|
# We should be careful not to filter historical data, as some memory leaks may only become apparent after a long period of time. Any kind of filtering may prevent us from detecting such a leak.
|
15
15
|
class Monitor
|
16
|
-
# We only track heap size changes greater than this threshold
|
16
|
+
# We only track heap size changes greater than this threshold, across the DEFAULT_INTERVAL.
|
17
17
|
# True memory leaks will eventually hit this threshold, while small fluctuations will not.
|
18
|
-
DEFAULT_THRESHOLD = 1024*10
|
18
|
+
DEFAULT_THRESHOLD = 1024*1024*10
|
19
19
|
|
20
20
|
# We track the last N heap size increases.
|
21
21
|
# If the heap size is not stabilizing within the specified limit, we can assume there is a leak.
|
@@ -24,12 +24,12 @@ module Memory
|
|
24
24
|
|
25
25
|
# Create a new monitor.
|
26
26
|
#
|
27
|
-
# @parameter maximum [Numeric] The initial maximum heap size, from which we willl track increases, in
|
28
|
-
# @parameter threshold [Numeric] The threshold for heap size increases, in
|
27
|
+
# @parameter maximum [Numeric] The initial maximum heap size, from which we willl track increases, in bytes.
|
28
|
+
# @parameter threshold [Numeric] The threshold for heap size increases, in bytes.
|
29
29
|
# @parameter limit [Numeric] The limit for the number of heap size increases, before we assume a memory leak.
|
30
|
-
# @
|
31
|
-
def initialize(
|
32
|
-
@
|
30
|
+
# @parameter [Integer] The process ID to monitor.
|
31
|
+
def initialize(process_id = Process.pid, maximum: nil, threshold: DEFAULT_THRESHOLD, limit: DEFAULT_LIMIT)
|
32
|
+
@process_id = process_id
|
33
33
|
|
34
34
|
@maximum = maximum
|
35
35
|
@threshold = threshold
|
@@ -40,8 +40,25 @@ module Memory
|
|
40
40
|
@current = nil
|
41
41
|
end
|
42
42
|
|
43
|
+
# @returns [Hash] A serializable representation of the cluster.
|
44
|
+
def as_json(...)
|
45
|
+
{
|
46
|
+
process_id: @process_id,
|
47
|
+
current: @current,
|
48
|
+
maximum: @maximum,
|
49
|
+
threshold: @threshold,
|
50
|
+
limit: @limit,
|
51
|
+
count: @count,
|
52
|
+
}
|
53
|
+
end
|
54
|
+
|
55
|
+
# @returns [String] The JSON representation of the cluster.
|
56
|
+
def to_json(...)
|
57
|
+
as_json.to_json(...)
|
58
|
+
end
|
59
|
+
|
43
60
|
# @attribute [Integer] The process ID to monitor.
|
44
|
-
attr :
|
61
|
+
attr :process_id
|
45
62
|
|
46
63
|
# @attribute [Numeric] The current maximum heap size.
|
47
64
|
attr :maximum
|
@@ -59,10 +76,10 @@ module Memory
|
|
59
76
|
#
|
60
77
|
# Even thought the absolute value of this number may not very useful, the relative change is useful for detecting memory leaks, and it works on most platforms.
|
61
78
|
#
|
62
|
-
# @returns [Numeric] Memory usage size in
|
79
|
+
# @returns [Numeric] Memory usage size in bytes.
|
63
80
|
private def memory_usage
|
64
|
-
IO.popen(["ps", "-o", "rss=", @
|
65
|
-
return Integer(io.readlines.last)
|
81
|
+
IO.popen(["ps", "-o", "rss=", @process_id.to_s]) do |io|
|
82
|
+
return Integer(io.readlines.last) * 1024
|
66
83
|
end
|
67
84
|
end
|
68
85
|
|
data/lib/memory/leak/version.rb
CHANGED
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: memory-leak
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
@@ -36,7 +36,7 @@ cert_chain:
|
|
36
36
|
Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
|
37
37
|
voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
|
38
38
|
-----END CERTIFICATE-----
|
39
|
-
date: 2025-02-
|
39
|
+
date: 2025-02-26 00:00:00.000000000 Z
|
40
40
|
dependencies: []
|
41
41
|
executables: []
|
42
42
|
extensions: []
|
metadata.gz.sig
CHANGED
Binary file
|