memory 0.11.0 → 0.12.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/context/getting-started.md +2 -2
- data/lib/memory/cache.rb +13 -5
- data/lib/memory/graph.rb +18 -8
- data/lib/memory/sampler.rb +2 -5
- data/lib/memory/usage.rb +14 -1
- data/lib/memory/version.rb +1 -1
- data/lib/memory.rb +8 -0
- data/readme.md +4 -4
- data/releases.md +4 -0
- data.tar.gz.sig +0 -0
- metadata +3 -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: 629175076a1c5aaf4cc1c75ea5bd8bcbb2b0366a2bfab17b6b95dc6b5834db12
|
|
4
|
+
data.tar.gz: 5a9a623b425a324c3d9692e1d20bda001cbc6de12c9e6c01035044964ecb5942
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 28d5d336d183df4140d6ab94a24ed69974598daa544ece8590cd37d3e0be7d3dbe38db69a6965eacb35107822cc1af93efd8bcf85d6f49076c73b8490b5ac603
|
|
7
|
+
data.tar.gz: aefccd3ad62ff34cd869ef52709f82b44323e273dd96da80ecf8af8a792cfc69bbea32f6b44011fd08e8bb9364e758bccb6685dcd8fc042e18c372b01b2d7137
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/context/getting-started.md
CHANGED
|
@@ -197,7 +197,7 @@ report = Memory::Report.new([
|
|
|
197
197
|
sampler = Memory::Sampler.new
|
|
198
198
|
sampler.run do
|
|
199
199
|
# Your code here
|
|
200
|
-
10000.times
|
|
200
|
+
10000.times{"test string"}
|
|
201
201
|
end
|
|
202
202
|
|
|
203
203
|
# Add samples to the custom report:
|
|
@@ -221,7 +221,7 @@ Reports can be exported as JSON for integration with other tools:
|
|
|
221
221
|
``` ruby
|
|
222
222
|
report = Memory.report do
|
|
223
223
|
# Your code
|
|
224
|
-
data = Array.new(1000)
|
|
224
|
+
data = Array.new(1000){{value: rand(1000)}}
|
|
225
225
|
end
|
|
226
226
|
|
|
227
227
|
# Export as JSON:
|
data/lib/memory/cache.rb
CHANGED
|
@@ -17,7 +17,7 @@ module Memory
|
|
|
17
17
|
# Initialize a new cache with empty lookup tables.
|
|
18
18
|
def initialize
|
|
19
19
|
@gem_guess_cache = Hash.new
|
|
20
|
-
@location_cache = Hash.new
|
|
20
|
+
@location_cache = Hash.new{|h, k| h[k] = Hash.new.compare_by_identity}
|
|
21
21
|
@class_name_cache = Hash.new.compare_by_identity
|
|
22
22
|
@string_cache = Hash.new
|
|
23
23
|
end
|
|
@@ -56,14 +56,22 @@ module Memory
|
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
# Look up and cache a string value.
|
|
59
|
+
#
|
|
60
|
+
# This maps the original string to a shortened representation.
|
|
61
|
+
#
|
|
59
62
|
# Strings are truncated to 64 characters to reduce memory usage.
|
|
60
63
|
# @parameter obj [String] The string object to cache.
|
|
61
64
|
# @returns [String] A cached copy of the string (truncated to 64 characters).
|
|
62
65
|
def lookup_string(obj)
|
|
63
|
-
# This string is shortened to
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
66
|
+
# This string is shortened to 64 characters which is what the string report shows. The string report (by value) can still list unique strings longer than 64 characters separately because the `object_id` of the shortened string will be different.
|
|
67
|
+
@string_cache[obj] ||= obj[0, 64]
|
|
68
|
+
rescue RuntimeError => error
|
|
69
|
+
# It is possible for the String to be temporarily locked from another Fiber which raises an error when we try to use it as a hash key. i.e: `Socket#read` locks a buffer string while reading data into it. In this case we `#dup`` the string to get an unlocked copy.
|
|
70
|
+
if error.message == "can't modify string; temporarily locked"
|
|
71
|
+
@string_cache[obj.dup] ||= obj[0, 64]
|
|
72
|
+
else
|
|
73
|
+
raise
|
|
74
|
+
end
|
|
67
75
|
end
|
|
68
76
|
end
|
|
69
77
|
end
|
data/lib/memory/graph.rb
CHANGED
|
@@ -13,6 +13,11 @@ module Memory
|
|
|
13
13
|
|
|
14
14
|
# Represents a node in the object graph with usage information.
|
|
15
15
|
class Node
|
|
16
|
+
# Initialize a new node in the object graph.
|
|
17
|
+
# @parameter object [Object] The object this node represents.
|
|
18
|
+
# @parameter usage [Usage] The memory usage of this object.
|
|
19
|
+
# @parameter parent [Node | Nil] The parent node in the traversal tree.
|
|
20
|
+
# @parameter reference [Symbol | Nil] The reference type from parent to this object.
|
|
16
21
|
def initialize(object, usage = Usage.new, parent = nil, reference: nil)
|
|
17
22
|
@object = object
|
|
18
23
|
@usage = usage
|
|
@@ -151,16 +156,21 @@ module Memory
|
|
|
151
156
|
# @parameter options [Hash] Options for JSON serialization.
|
|
152
157
|
# @returns [Hash] A hash representation of this node.
|
|
153
158
|
def as_json(*)
|
|
154
|
-
{
|
|
159
|
+
json = {
|
|
155
160
|
path: path,
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
total_usage: total_usage.as_json,
|
|
162
|
-
children: @children&.transform_values(&:as_json)
|
|
161
|
+
object: {
|
|
162
|
+
class: @object.class.name,
|
|
163
|
+
object_id: @object.object_id
|
|
164
|
+
},
|
|
165
|
+
usage: @usage.as_json,
|
|
163
166
|
}
|
|
167
|
+
|
|
168
|
+
if @children&.any?
|
|
169
|
+
json[:total_usage] = total_usage.as_json
|
|
170
|
+
json[:children] = @children.transform_values(&:as_json)
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
return json
|
|
164
174
|
end
|
|
165
175
|
|
|
166
176
|
# Convert this node to a JSON string.
|
data/lib/memory/sampler.rb
CHANGED
|
@@ -32,8 +32,8 @@ module Memory
|
|
|
32
32
|
@cache = cache
|
|
33
33
|
|
|
34
34
|
self.register_type(0x01, Allocation,
|
|
35
|
-
packer: ->(instance){self.pack(instance.pack)},
|
|
36
|
-
unpacker: ->(data){Allocation.unpack(@cache, self.unpack(data))},
|
|
35
|
+
packer: ->(instance) {self.pack(instance.pack)},
|
|
36
|
+
unpacker: ->(data) {Allocation.unpack(@cache, self.unpack(data))},
|
|
37
37
|
)
|
|
38
38
|
|
|
39
39
|
self.register_type(0x02, Symbol)
|
|
@@ -290,9 +290,6 @@ module Memory
|
|
|
290
290
|
class_name = @cache.lookup_class_name(klass)
|
|
291
291
|
value = (klass == String) ? @cache.lookup_string(object) : nil
|
|
292
292
|
|
|
293
|
-
# compensate for API bug
|
|
294
|
-
memsize = rvalue_size if memsize > 100_000_000_000
|
|
295
|
-
|
|
296
293
|
allocation = Allocation.new(@cache, class_name, file, line, memsize, value, false)
|
|
297
294
|
|
|
298
295
|
@allocated << allocation
|
data/lib/memory/usage.rb
CHANGED
|
@@ -9,7 +9,13 @@ require "set"
|
|
|
9
9
|
require "objspace"
|
|
10
10
|
|
|
11
11
|
module Memory
|
|
12
|
+
# Tracks memory usage statistics including size and object count.
|
|
13
|
+
#
|
|
14
|
+
# Can be used to measure allocations or compute usage of object graphs.
|
|
12
15
|
class Usage
|
|
16
|
+
# Initialize a new usage tracker.
|
|
17
|
+
# @parameter size [Integer] The total size in bytes.
|
|
18
|
+
# @parameter count [Integer] The total count of objects.
|
|
13
19
|
def initialize(size = 0, count = 0)
|
|
14
20
|
@size = size
|
|
15
21
|
@count = count
|
|
@@ -103,17 +109,24 @@ module Memory
|
|
|
103
109
|
return new(size, count)
|
|
104
110
|
end
|
|
105
111
|
|
|
112
|
+
# Convert this usage to a JSON-compatible hash.
|
|
113
|
+
# @parameter options [Hash | Nil] Optional JSON serialization options.
|
|
114
|
+
# @returns [Hash] Hash with `:size` and `:count` keys.
|
|
106
115
|
def as_json(...)
|
|
107
116
|
{
|
|
108
117
|
size: @size,
|
|
109
|
-
|
|
118
|
+
count: @count
|
|
110
119
|
}
|
|
111
120
|
end
|
|
112
121
|
|
|
122
|
+
# Convert this usage to a JSON string.
|
|
123
|
+
# @returns [String] JSON representation of this usage.
|
|
113
124
|
def to_json(...)
|
|
114
125
|
as_json.to_json(...)
|
|
115
126
|
end
|
|
116
127
|
|
|
128
|
+
# Generate a human-readable string representation.
|
|
129
|
+
# @returns [String] Formatted string showing size and allocation count.
|
|
117
130
|
def to_s
|
|
118
131
|
"(#{Memory.formatted_bytes(@size)} in #{@count} allocations)"
|
|
119
132
|
end
|
data/lib/memory/version.rb
CHANGED
data/lib/memory.rb
CHANGED
data/readme.md
CHANGED
|
@@ -94,6 +94,10 @@ end
|
|
|
94
94
|
|
|
95
95
|
Please see the [project releases](https://socketry.github.io/memory/releases/index) for all releases.
|
|
96
96
|
|
|
97
|
+
### v0.11.1
|
|
98
|
+
|
|
99
|
+
- Compressed `Memory::Graph::Node` JSON representation for leaf nodes.
|
|
100
|
+
|
|
97
101
|
### v0.11.0
|
|
98
102
|
|
|
99
103
|
- Remove support for `Memory::Usage.of(..., via:)` and instead use `Memory::Graph.for` which collects more detailed usage until the specified depth, at which point it delgates to `Memory::Usage.of`. This should be more practical.
|
|
@@ -132,10 +136,6 @@ Please see the [project releases](https://socketry.github.io/memory/releases/ind
|
|
|
132
136
|
|
|
133
137
|
- Ensure aggregate keys are safe for serialization (and printing).
|
|
134
138
|
|
|
135
|
-
### v0.7.0
|
|
136
|
-
|
|
137
|
-
- Add `Memory::Sampler#as_json` and `#to_json`.
|
|
138
|
-
|
|
139
139
|
## Contributing
|
|
140
140
|
|
|
141
141
|
We welcome contributions to this project.
|
data/releases.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# Releases
|
|
2
2
|
|
|
3
|
+
## v0.11.1
|
|
4
|
+
|
|
5
|
+
- Compressed `Memory::Graph::Node` JSON representation for leaf nodes.
|
|
6
|
+
|
|
3
7
|
## v0.11.0
|
|
4
8
|
|
|
5
9
|
- Remove support for `Memory::Usage.of(..., via:)` and instead use `Memory::Graph.for` which collects more detailed usage until the specified depth, at which point it delgates to `Memory::Usage.of`. This should be more practical.
|
data.tar.gz.sig
CHANGED
|
Binary file
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: memory
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.12.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sam Saffron
|
|
@@ -29,6 +29,7 @@ authors:
|
|
|
29
29
|
- Olle Jonsson
|
|
30
30
|
- Vasily Kolesnikov
|
|
31
31
|
- William Tabi
|
|
32
|
+
- Michael Go
|
|
32
33
|
bindir: bin
|
|
33
34
|
cert_chain:
|
|
34
35
|
- |
|
|
@@ -145,7 +146,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
145
146
|
- !ruby/object:Gem::Version
|
|
146
147
|
version: '0'
|
|
147
148
|
requirements: []
|
|
148
|
-
rubygems_version: 3.
|
|
149
|
+
rubygems_version: 3.6.9
|
|
149
150
|
specification_version: 4
|
|
150
151
|
summary: Memory profiling routines for Ruby 2.3+
|
|
151
152
|
test_files: []
|
metadata.gz.sig
CHANGED
|
Binary file
|