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