rmem 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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
+