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.
- data/LICENSE +51 -0
- data/README +11 -0
- data/Rakefile +61 -0
- data/ext/extconf.rb +13 -0
- data/ext/rmem.c +118 -0
- 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
|
data/Rakefile
ADDED
@@ -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
|
data/ext/extconf.rb
ADDED
@@ -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')
|
data/ext/rmem.c
ADDED
@@ -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
|
+
|