memstat 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +71 -7
- data/lib/memstat/version.rb +1 -1
- data/memstat.gemspec +8 -8
- data/test/test_memstat.rb +2 -3
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 90119832e41e4b1f94fa4d5ed312c21d8b7a152b
|
4
|
+
data.tar.gz: b4b527bfb4596bda0a4597beef32b6fb402a1d2a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 60a9c14475244b516db3eac3f375cb4cbf39161849a91e58949b4cd16ee75f1802a05fd3fa0f593aea0f4a81cda6eb1d59e767cb89ebec7a32589a0db8688709
|
7
|
+
data.tar.gz: c82ce0b893f7ac0b7e3a4f5202fc11e3dcf4b33333104b4e4114dee2c609cbe3f26d836463923d86108d3ca08b17257d5be901f0dbb2670749cf48b5361b88bb
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Memstat: Fast memory statistics &
|
1
|
+
# Memstat: Fast memory statistics & better out-of-band GC
|
2
2
|
|
3
3
|
Ruby 2.1 introduced generational garbage collection. It is a major improvement in terms of shorter GC pauses and overall higher throughput, but that comes with a [drawback of potential memory bloat](http://www.omniref.com/blog/blog/2014/03/27/ruby-garbage-collection-still-not-ready-for-production/).
|
4
4
|
|
@@ -10,26 +10,39 @@ If you've ever called the `ps -o rss` command from inside a Ruby process to capt
|
|
10
10
|
|
11
11
|
That's because shelling out `ps` creates an entire copy of the ruby process - typically 70-150MB for a Rails app - then wipe out those memory with the executable of `ps`. Even with copy-on-write and POSIX-spawn optimization, you can't beat the speed of directly reading statistics from memory that is maintained by the kernel.
|
12
12
|
|
13
|
-
|
13
|
+
For a typical Rails app, memstat is 130 times faster than `ps -o rss`:
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
Benchmark.bm(10) do |x|
|
17
|
+
x.report("ps:") { 100.times.each { `ps -o rss -p #{Process.pid}`.strip.to_i } }
|
18
|
+
x.report("memstat:") { 100.times.each { Memstat::Proc::Status.new(:pid => Process.pid).rss } }
|
19
|
+
end
|
14
20
|
|
15
|
-
```
|
16
21
|
user system total real
|
17
|
-
ps: 0.
|
18
|
-
memstat: 0.
|
22
|
+
ps: 0.110000 4.280000 6.260000 ( 6.302661)
|
23
|
+
memstat: 0.040000 0.000000 0.040000 ( 0.048166)
|
19
24
|
```
|
20
25
|
|
26
|
+
Tested on [Linode](https://www.linode.com) with a Rails app of 140MB memory usage.
|
27
|
+
|
21
28
|
## Installation
|
22
29
|
|
23
30
|
Add this line to your application's Gemfile:
|
24
31
|
|
25
|
-
|
32
|
+
```ruby
|
33
|
+
gem 'memstat'
|
34
|
+
```
|
26
35
|
|
27
36
|
Or install it yourself as:
|
28
37
|
|
29
|
-
|
38
|
+
```sh
|
39
|
+
$ gem install memstat
|
40
|
+
```
|
30
41
|
|
31
42
|
## Usage
|
32
43
|
|
44
|
+
Check the memory usage, and run GC if it's too big. Note that current version only supports Linux.
|
45
|
+
|
33
46
|
```ruby
|
34
47
|
if Memstat.linux?
|
35
48
|
status = Memstat::Proc::Status.new(pid: Process.pid)
|
@@ -47,6 +60,57 @@ require 'memstat'
|
|
47
60
|
use Memstat::OobGC::Unicorn, 150*(1024**2) # Invoke GC if the process is bigger than 150MB
|
48
61
|
```
|
49
62
|
|
63
|
+
Other methods are:
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
status.peak # Peak VM size
|
67
|
+
status.size # Current VM size
|
68
|
+
status.lck # mlock-ed memory size (unswappable)
|
69
|
+
status.pin # pinned memory size (unswappable and fixed physical address)
|
70
|
+
status.hwm # Peak physical memory size
|
71
|
+
status.rss # Current physical memory size
|
72
|
+
status.data # Data area size
|
73
|
+
status.stk # Stack size
|
74
|
+
status.exe # Text (executable) size
|
75
|
+
status.lib # Loaded library size
|
76
|
+
status.pte # Page table size
|
77
|
+
status.swap # Swap size
|
78
|
+
```
|
79
|
+
|
80
|
+
See [details](http://ewx.livejournal.com/579283.html) for each item.
|
81
|
+
|
82
|
+
## Commandline
|
83
|
+
|
84
|
+
memstat also comes with a command line utility to report detailed memory statistics by aggregating `/proc/[pid]/smaps`.
|
85
|
+
|
86
|
+
This is useful to examine the effectiveness of copy-on-write for forking servers like Unicorn.
|
87
|
+
|
88
|
+
Usage:
|
89
|
+
|
90
|
+
```sh
|
91
|
+
$ memstat smaps [PID]
|
92
|
+
```
|
93
|
+
|
94
|
+
will give you the following result:
|
95
|
+
|
96
|
+
```sh
|
97
|
+
Process: 13405
|
98
|
+
Command Line: unicorn master -D -E staging -c /path/to/current/config/unicorn.rb
|
99
|
+
Memory Summary:
|
100
|
+
size 274,852 kB
|
101
|
+
rss 131,020 kB
|
102
|
+
pss 66,519 kB
|
103
|
+
shared_clean 8,408 kB
|
104
|
+
shared_dirty 95,128 kB
|
105
|
+
private_clean 8 kB
|
106
|
+
private_dirty 27,476 kB
|
107
|
+
swap 0 kB
|
108
|
+
```
|
109
|
+
|
110
|
+
In this case, 103,536 kB out of 131,020 kB is shared, which means 79% of its memory is shared with worker processes.
|
111
|
+
|
112
|
+
For more details, [read this gist](https://gist.github.com/kenn/5105175).
|
113
|
+
|
50
114
|
## Contributing
|
51
115
|
|
52
116
|
1. Fork it
|
data/lib/memstat/version.rb
CHANGED
data/memstat.gemspec
CHANGED
@@ -4,19 +4,19 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
require 'memstat/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
7
|
+
spec.name = 'memstat'
|
8
8
|
spec.version = Memstat::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
11
|
-
spec.description = %q{Fast memory statistics}
|
12
|
-
spec.summary = %q{Fast memory statistics}
|
13
|
-
spec.homepage =
|
14
|
-
spec.license =
|
9
|
+
spec.authors = ['Kenn Ejima']
|
10
|
+
spec.email = ['kenn.ejima@gmail.com']
|
11
|
+
spec.description = %q{Fast memory statistics and better out-of-band GC}
|
12
|
+
spec.summary = %q{Fast memory statistics and better out-of-band GC}
|
13
|
+
spec.homepage = 'https://github.com/kenn/memstat'
|
14
|
+
spec.license = 'MIT'
|
15
15
|
|
16
16
|
spec.files = `git ls-files`.split($/)
|
17
17
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
-
spec.require_paths = [
|
19
|
+
spec.require_paths = ['lib']
|
20
20
|
|
21
21
|
spec.add_development_dependency 'bundler'
|
22
22
|
spec.add_development_dependency 'rake'
|
data/test/test_memstat.rb
CHANGED
@@ -35,7 +35,6 @@ class TestCli < Minitest::Test
|
|
35
35
|
assert_equal status.hwm, 131044 * 1024
|
36
36
|
assert_equal status.rss, 131044 * 1024
|
37
37
|
assert_equal status.data, 133064 * 1024
|
38
|
-
assert_equal status.peak, 277756 * 1024
|
39
38
|
assert_equal status.stk, 136 * 1024
|
40
39
|
assert_equal status.exe, 4 * 1024
|
41
40
|
assert_equal status.lib, 21524 * 1024
|
@@ -46,8 +45,8 @@ class TestCli < Minitest::Test
|
|
46
45
|
def test_benchmark
|
47
46
|
n = 100
|
48
47
|
Benchmark.bm(10) do |x|
|
49
|
-
x.report("ps:") { n.times.each { `ps -o rss -p #{
|
50
|
-
x.report("memstat:") { n.times.each { Memstat::Proc::Status.new(:
|
48
|
+
x.report("ps:") { n.times.each { `ps -o rss -p #{Process.pid}`.strip.split.last.to_i } }
|
49
|
+
x.report("memstat:") { n.times.each { Memstat::Proc::Status.new(:pid => Process.pid).rss } }
|
51
50
|
end
|
52
51
|
end
|
53
52
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: memstat
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kenn Ejima
|
@@ -66,7 +66,7 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
-
description: Fast memory statistics
|
69
|
+
description: Fast memory statistics and better out-of-band GC
|
70
70
|
email:
|
71
71
|
- kenn.ejima@gmail.com
|
72
72
|
executables:
|
@@ -91,7 +91,7 @@ files:
|
|
91
91
|
- test/files/smaps.txt
|
92
92
|
- test/files/status.txt
|
93
93
|
- test/test_memstat.rb
|
94
|
-
homepage:
|
94
|
+
homepage: https://github.com/kenn/memstat
|
95
95
|
licenses:
|
96
96
|
- MIT
|
97
97
|
metadata: {}
|
@@ -114,7 +114,7 @@ rubyforge_project:
|
|
114
114
|
rubygems_version: 2.2.0.rc.1
|
115
115
|
signing_key:
|
116
116
|
specification_version: 4
|
117
|
-
summary: Fast memory statistics
|
117
|
+
summary: Fast memory statistics and better out-of-band GC
|
118
118
|
test_files:
|
119
119
|
- test/files/smaps.txt
|
120
120
|
- test/files/status.txt
|