rmemlimit 0.1

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.
data/CHANGELOG ADDED
@@ -0,0 +1 @@
1
+ v0.1. Proof of concept
data/Manifest ADDED
@@ -0,0 +1,6 @@
1
+ CHANGELOG
2
+ README.md
3
+ Rakefile
4
+ lib/rmemlimit.rb
5
+ test/test_all.rb
6
+ Manifest
data/README.md ADDED
@@ -0,0 +1,37 @@
1
+
2
+ ## Rmemlimit gem
3
+
4
+ The garbage collector in Ruby 1.x is blocking, and runs whenever there is a
5
+ need to allocate more memory for new objects.
6
+
7
+ In a large application (eg. Rails) it runs many times per second, saving
8
+ memory but hurting performance.
9
+
10
+ #### Run GC less often
11
+
12
+ To increase performance, you can use this gem to run the GC once per second
13
+ instead, in a background thread.
14
+
15
+ gem 'rmemlimit' # in your Gemfile
16
+
17
+
18
+ #### Set a memory limit for GC (requires linux /proc)
19
+
20
+ If you know roughly how much RAM you want your app to use, you can set that
21
+ and GC will run whenever it is exceeded. Resident Set Size is checked once
22
+ per second. Example to limit to 500MB:
23
+
24
+ Rmemlimit.gc_mb = 500
25
+
26
+ (Or you can use the RUBY_GC_MB environment variable).
27
+
28
+
29
+ #### Set a hard memory limit for Ruby
30
+
31
+ If your application sometimes eats too much memory and you'd rather have it
32
+ kill itself when it passes a threshold, you can do limit to say 1000MB:
33
+
34
+ Rmemlimit.kill_mb = 1000
35
+
36
+ (Or you can use the RUBY_KILL_MB environment variable)
37
+
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'echoe'
2
+
3
+ Echoe.new("rmemlimit") do |p|
4
+ p.author = "Andrew Snow"
5
+ p.email = 'andrew@modulus.org'
6
+ p.summary = "Slow down garbage collector & limit ruby process memory"
7
+ p.url = "https://github.com/andys/rmemlimit"
8
+ end
data/lib/rmemlimit.rb ADDED
@@ -0,0 +1,55 @@
1
+
2
+ class Rmemlimit
3
+
4
+ class << self
5
+ attr_accessor :gc_mb, :kill_mb
6
+
7
+ def gcthread
8
+ @gcthread ||= Thread.new do
9
+ loop do
10
+ mb = rss_mb
11
+ if kill_mb && mb > kill_mb
12
+ STDERR.puts "#{self}: Exceeded kill memory limit (#{mb} > #{kill_Mb} MB)"
13
+ Process.kill(9, $$)
14
+ elsif gc_mb && mb > gc_mb
15
+ run_gc
16
+ elsif mb == 0 || !gc_mb || !kill_mb
17
+ run_gc
18
+ end
19
+ sleep 1
20
+ end
21
+ end
22
+ end
23
+
24
+ def run_gc
25
+ GC.enable
26
+ GC.start
27
+ GC.disable
28
+ end
29
+
30
+ def pagesize
31
+ 4096
32
+ end
33
+
34
+ def rss_mb
35
+ rss_kb >> 10
36
+ end
37
+
38
+ def rss_kb
39
+ pagesize * (File.read("/proc/#{$$}/statm").split(' ')[1].to_i rescue 0) >> 10
40
+ end
41
+
42
+ def setup
43
+ self.gc_mb = ENV['RUBY_GC_MB'].to_i if ENV['RUBY_GC_MB']
44
+ if ENV['RUBY_KILL_MB']
45
+ self.kill_mb = ENV['RUBY_KILL_MB'].to_i
46
+ self.kill_mb = nil unless Rmemlimit.kill_mb > 1
47
+ end
48
+ GC.disable
49
+ self.gcthread
50
+ end
51
+ end
52
+
53
+ end
54
+
55
+ Rmemlimit.setup
data/rmemlimit.gemspec ADDED
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "rmemlimit"
5
+ s.version = "0.1"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Andrew Snow"]
9
+ s.date = "2012-12-28"
10
+ s.description = "Slow down garbage collector & limit ruby process memory"
11
+ s.email = "andrew@modulus.org"
12
+ s.extra_rdoc_files = ["CHANGELOG", "README.md", "lib/rmemlimit.rb"]
13
+ s.files = ["CHANGELOG", "README.md", "Rakefile", "lib/rmemlimit.rb", "test/test_all.rb", "Manifest", "rmemlimit.gemspec"]
14
+ s.homepage = "https://github.com/andys/rmemlimit"
15
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Rmemlimit", "--main", "README.md"]
16
+ s.require_paths = ["lib"]
17
+ s.rubyforge_project = "rmemlimit"
18
+ s.rubygems_version = "1.8.24"
19
+ s.summary = "Slow down garbage collector & limit ruby process memory"
20
+ s.test_files = ["test/test_all.rb"]
21
+
22
+ if s.respond_to? :specification_version then
23
+ s.specification_version = 3
24
+
25
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
26
+ else
27
+ end
28
+ else
29
+ end
30
+ end
data/test/test_all.rb ADDED
@@ -0,0 +1,28 @@
1
+ require "#{File.dirname(__FILE__)}/../lib/rmemlimit"
2
+ require 'test/unit'
3
+
4
+ class TestRmemlimit < Test::Unit::TestCase
5
+
6
+ def test_rss_kb
7
+ kb = Rmemlimit.rss_kb
8
+ assert(kb > 0)
9
+
10
+ assert_equal "VmRSS:\t%8d kB\n" % kb,
11
+ File.read("/proc/#{$$}/status").lines.grep(/VmRSS/).first
12
+ end
13
+
14
+ def test_run_gc
15
+ gccount = GC.stat[:count] + 1
16
+ sleep 1.1
17
+ assert_equal gccount, GC.stat[:count]
18
+ end
19
+
20
+ def test_gc_mb
21
+ Rmemlimit.gc_mb = Rmemlimit.rss_mb
22
+ gccount = GC.stat[:count] + 1
23
+ flibble = 'x' * 1024 * 1024
24
+ sleep 1.1
25
+ assert_equal gccount, GC.stat[:count]
26
+ end
27
+
28
+ end
metadata ADDED
@@ -0,0 +1,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rmemlimit
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: '0.1'
6
+ platform: ruby
7
+ authors:
8
+ - Andrew Snow
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-12-28 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Slow down garbage collector & limit ruby process memory
15
+ email: andrew@modulus.org
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files:
19
+ - CHANGELOG
20
+ - README.md
21
+ - lib/rmemlimit.rb
22
+ files:
23
+ - CHANGELOG
24
+ - README.md
25
+ - Rakefile
26
+ - lib/rmemlimit.rb
27
+ - test/test_all.rb
28
+ - Manifest
29
+ - rmemlimit.gemspec
30
+ homepage: https://github.com/andys/rmemlimit
31
+ licenses: []
32
+ post_install_message:
33
+ rdoc_options:
34
+ - --line-numbers
35
+ - --inline-source
36
+ - --title
37
+ - Rmemlimit
38
+ - --main
39
+ - README.md
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ none: false
48
+ required_rubygems_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ! '>='
51
+ - !ruby/object:Gem::Version
52
+ version: '1.2'
53
+ none: false
54
+ requirements: []
55
+ rubyforge_project: rmemlimit
56
+ rubygems_version: 1.8.24
57
+ signing_key:
58
+ specification_version: 3
59
+ summary: Slow down garbage collector & limit ruby process memory
60
+ test_files:
61
+ - test/test_all.rb