rmem 1.0.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.
Files changed (6) hide show
  1. data/LICENSE +51 -0
  2. data/README +11 -0
  3. data/Rakefile +61 -0
  4. data/ext/extconf.rb +13 -0
  5. data/ext/rmem.c +118 -0
  6. metadata +61 -0
data/LICENSE ADDED
@@ -0,0 +1,51 @@
1
+ Copyright (c) 2009 Todd A Fisher (todd DOT fisher AT gmail DOT com ).
2
+ Rmem is free software licensed under the following terms:
3
+
4
+ 1. You may make and give away verbatim copies of the source form of the
5
+ software without restriction, provided that you duplicate all of the
6
+ original copyright notices and associated disclaimers.
7
+
8
+ 2. You may modify your copy of the software in any way, provided that
9
+ you do at least ONE of the following:
10
+
11
+ a) place your modifications in the Public Domain or otherwise
12
+ make them Freely Available, such as by posting said
13
+ modifications to Usenet or an equivalent medium, or by allowing
14
+ the author to include your modifications in the software.
15
+
16
+ b) use the modified software only within your corporation or
17
+ organization.
18
+
19
+ c) give non-standard binaries non-standard names, with
20
+ instructions on where to get the original software distribution.
21
+
22
+ d) make other distribution arrangements with the author.
23
+
24
+ 3. You may distribute the software in object code or binary form,
25
+ provided that you do at least ONE of the following:
26
+
27
+ a) distribute the binaries and library files of the software,
28
+ together with instructions (in the manual page or equivalent)
29
+ on where to get the original distribution.
30
+
31
+ b) accompany the distribution with the machine-readable source of
32
+ the software.
33
+
34
+ c) give non-standard binaries non-standard names, with
35
+ instructions on where to get the original software distribution.
36
+
37
+ d) make other distribution arrangements with the author.
38
+
39
+ 4. You may modify and include the part of the software into any other
40
+ software (possibly commercial).
41
+
42
+ 5. The scripts and library files supplied as input to or produced as
43
+ output from the software do not automatically fall under the
44
+ copyright of the software, but belong to whomever generated them,
45
+ and may be sold commercially, and may be aggregated with this
46
+ software.
47
+
48
+ 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
49
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
50
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
51
+ PURPOSE.
data/README ADDED
@@ -0,0 +1,11 @@
1
+ Ruby Memory Measure
2
+ -------------------
3
+
4
+ Ever wonder how much memory your process is using? Have you ever wanted to know at specific points of execution what the memory usage looks like?
5
+ This should give you a similar sense of the process memory usage as looking at top, task manager or activity monitor. The advantage is you don't have
6
+ to run an external tool to capture what's going on inside your process.
7
+
8
+ bytes = RMem::Report.memory
9
+ puts format("footprint: %d bytes, %.2f kbytes, and %.4f MB", bytes, bytes/1024.0, bytes/1024.0/1024.0)
10
+
11
+ For ruby see test.rb
@@ -0,0 +1,61 @@
1
+
2
+ require 'rake/clean'
3
+ CURRENT_VERSION = "1.0.0"
4
+ RMEM_SO = "ext/rmem.#{Config::MAKEFILE_CONFIG['DLEXT']}"
5
+ # Make tasks -----------------------------------------------------
6
+ MAKECMD = ENV['MAKE_CMD'] || 'make'
7
+ MAKEOPTS = ENV['MAKE_OPTS'] || ''
8
+ CLEAN.include '**/*.o'
9
+ CLEAN.include "**/*.#{Config::MAKEFILE_CONFIG['DLEXT']}"
10
+ CLOBBER.include '**/*.log'
11
+ CLOBBER.include '**/Makefile'
12
+ CLOBBER.include '**/extconf.h'
13
+ CLOBBER.include '**/rmem_config.h'
14
+
15
+ file 'ext/Makefile' => 'ext/extconf.rb' do
16
+ Dir.chdir('ext') do
17
+ ruby "extconf.rb #{ENV['EXTCONF_OPTS']}"
18
+ end
19
+ end
20
+
21
+ def make(target = '')
22
+ Dir.chdir('ext') do
23
+ pid = system("#{MAKECMD} #{MAKEOPTS} #{target}")
24
+ $?.exitstatus
25
+ end
26
+ end
27
+
28
+ # Let make handle dependencies between c/o/so - we'll just run it.
29
+ file RMEM_SO => (['ext/Makefile'] + Dir['ext/*.c'] + Dir['ext/*.h']) do
30
+ m = make
31
+ fail "Make failed (status #{m})" unless m == 0
32
+ end
33
+
34
+ desc "Compile the shared object"
35
+ task :compile => [RMEM_SO]
36
+
37
+ task :default => :compile
38
+
39
+ desc 'Generate gem specification'
40
+ task :gemspec => :clobber do
41
+ require 'erb'
42
+ tspec = ERB.new(File.read(File.join(File.dirname(__FILE__),'ext','rmem.gemspec.erb')))
43
+ File.open(File.join(File.dirname(__FILE__),'rmem.gemspec'),'wb') do|f|
44
+ f << tspec.result
45
+ end
46
+ end
47
+
48
+ if ! defined?(Gem)
49
+ warn "Package Target requires RubyGEMs"
50
+ else
51
+ desc 'Build gem'
52
+ task :package => :gemspec do
53
+ require 'rubygems/specification'
54
+ spec_source = File.read File.join(File.dirname(__FILE__),'rmem.gemspec')
55
+ spec = nil
56
+ # see: http://gist.github.com/16215
57
+ Thread.new { spec = eval("$SAFE = 3\n#{spec_source}") }.join
58
+ spec.validate
59
+ Gem::Builder.new(spec).build
60
+ end
61
+ end
@@ -0,0 +1,13 @@
1
+ require 'mkmf'
2
+
3
+ dir_config('rmem')
4
+ checking_for '/proc file system' do
5
+ $defs.push( "-D HAVE_PROC" ) if File.exist?('/proc')
6
+ end
7
+ have_header('libproc.h')
8
+ have_header('windows.h')
9
+ have_header('psapi.h')
10
+ have_library('psapi')
11
+
12
+ create_header('rmem_config.h')
13
+ create_makefile('rmem')
@@ -0,0 +1,118 @@
1
+ #include <stdio.h>
2
+ #include <stdlib.h>
3
+ #include <string.h>
4
+ #include "rmem_config.h"
5
+ #if HAVE_LIBPROC_H
6
+ // see: http://stackoverflow.com/questions/220323/determine-process-info-programmatically-in-darwin-osx
7
+ # include <unistd.h>
8
+ # include <libproc.h>
9
+ #elif HAVE_PROC
10
+ // see: http://www.linuxforums.org/forum/linux-programming-scripting/11703-c-function-returns-cpu-memory-usage.html
11
+ # include <unistd.h>
12
+ #elif HAVE_WINDOWS_H
13
+ # include <windows.h>
14
+ # include <psapi.h>
15
+ #else
16
+ #error "No /proc or libproc.h"
17
+ #endif
18
+
19
+ #include <ruby.h>
20
+
21
+ static int report_memory_usage_by_pid(unsigned long pid, unsigned long *size)
22
+ {
23
+ #ifdef HAVE_PROC
24
+ char buf[30];
25
+ snprintf(buf, 30, "/proc/%lu/statm", pid);
26
+ FILE* pf = fopen(buf, "r");
27
+ if (pf) {
28
+ int r = fscanf(pf, "%lu", size);
29
+ fclose(pf);
30
+ return (r == 1) ? 0 : 1;
31
+ }
32
+ return 1;
33
+ #endif
34
+
35
+ #ifdef HAVE_LIBPROC_H
36
+ struct proc_taskinfo pt;
37
+ int ret = proc_pidinfo(pid, PROC_PIDTASKINFO, 0, &pt, sizeof(pt));
38
+ if( ret <= 0 ) {
39
+ return 1;
40
+ }
41
+ *size = pt.pti_resident_size;
42
+ return 0;
43
+
44
+ #endif
45
+ #ifdef HAVE_WINDOWS_H
46
+ HANDLE hProcess;
47
+ PROCESS_MEMORY_COUNTERS pmc;
48
+
49
+ hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid );
50
+ if (NULL == hProcess)
51
+ return 1;
52
+ if ( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc)) ) {
53
+ *size = pmc.PagefileUsage;
54
+ }
55
+
56
+ CloseHandle( hProcess );
57
+ return 0;
58
+ #endif
59
+ }
60
+
61
+ static int report_memory_usage(unsigned long *size)
62
+ {
63
+ unsigned long pid;
64
+ #ifdef HAVE_WINDOWS_H
65
+ pid = GetCurrentProcessId();
66
+ #else
67
+ pid = getpid();
68
+ #endif
69
+ return report_memory_usage_by_pid(pid, size);
70
+ }
71
+
72
+ static VALUE rb_rmem;
73
+ static VALUE rb_rmem_report;
74
+
75
+ static VALUE ruby_memory_report(VALUE self)
76
+ {
77
+ unsigned long bytes;
78
+ if( report_memory_usage(&bytes) ) {
79
+ rb_raise(rb_eRuntimeError, "Error detecting runtime memory usage");
80
+ }
81
+ return rb_int_new(bytes);
82
+ }
83
+
84
+ static VALUE ruby_memory_report_for(VALUE self, VALUE pid)
85
+ {
86
+ unsigned long bytes;
87
+ if( report_memory_usage_by_pid(FIX2LONG(pid), &bytes) ) {
88
+ rb_raise(rb_eRuntimeError, "Error detecting runtime memory usage");
89
+ }
90
+ return rb_int_new(bytes);
91
+ }
92
+
93
+
94
+ void Init_rmem()
95
+ {
96
+ rb_rmem = rb_define_module("RMem");
97
+ rb_rmem_report = rb_define_class_under( rb_rmem, "Report", rb_cObject );
98
+ rb_define_singleton_method(rb_rmem_report, "memory", ruby_memory_report, 0);
99
+ rb_define_singleton_method(rb_rmem_report, "memory_for", ruby_memory_report_for, 1);
100
+ }
101
+
102
+
103
+ #ifdef TEST_ENABLED
104
+
105
+ int main( int argc, char **argv )
106
+ {
107
+ char buffer[1024];
108
+ unsigned long memory_usage;
109
+
110
+ memset(buffer,0,sizeof(buffer));
111
+
112
+ report_memory_usage(&memory_usage);
113
+
114
+ printf("mem: %lu bytes\n", memory_usage);
115
+ return 0;
116
+ }
117
+
118
+ #endif
metadata ADDED
@@ -0,0 +1,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rmem
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Todd A. Fisher
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-12-26 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Measure approximate process memory
17
+ email: todd.fisher@gmail.com
18
+ executables: []
19
+
20
+ extensions:
21
+ - ext/extconf.rb
22
+ extra_rdoc_files:
23
+ - LICENSE
24
+ - README
25
+ files:
26
+ - LICENSE
27
+ - README
28
+ - Rakefile
29
+ - ext/extconf.rb
30
+ - ext/rmem.c
31
+ has_rdoc: true
32
+ homepage: http://rmem.rubyforge.org/
33
+ licenses: []
34
+
35
+ post_install_message:
36
+ rdoc_options:
37
+ - --main
38
+ - README
39
+ require_paths:
40
+ - ext
41
+ required_ruby_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: "0"
46
+ version:
47
+ required_rubygems_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: "0"
52
+ version:
53
+ requirements: []
54
+
55
+ rubyforge_project: rmem
56
+ rubygems_version: 1.3.5
57
+ signing_key:
58
+ specification_version: 3
59
+ summary: Ruby Memory Measurebindings
60
+ test_files: []
61
+