2015-02-01T09:01:46.965380+00:00 heroku[web.1]: source=web.1 dyno=heroku.28228261.c4fede81-d205-4dad-b07e-2ad6dcc49a0f sample#memory_total=186.27MB sample#memory_rss=180.75MB sample#memory_cache=5.52MB sample#memory_swap=0.00MB sample#memory_pgpgin=71767pages sample#memory_pgpgout=24081pages
- Resident Memory (
memory_rss): The portion of the dyno’s memory (megabytes) held in RAM.
2015-02-01T09:23:50.049734+00:00 heroku[web.1]: source=web.1 dyno=heroku.28228261.c4fede81-d205-4dad-b07e-2ad6dcc49a0f sample#memory_total=242.09MB sample#memory_rss=236.50MB sample#memory_cache=5.59MB sample#memory_swap=0.00MB sample#memory_pgpgin=97398pages sample#memory_pgpgout=35422pages
2015-02-01T09:23:38.787009+00:00 heroku[web.2]: source=web.2 dyno=heroku.28228261.9b8464db-9ab7-42e3-a61a-604a765f38be sample#memory_total=239.23MB sample#memory_rss=233.64MB sample#memory_cache=5.59MB sample#memory_swap=0.00MB sample#memory_pgpgin=95938pages sample#memory_pgpgout=34694pages
def memcheck(f):
"""
A crude decorator to memory check your web2py controller's functions.
False positives are possible if your controller function returns less than
common stuff.
Put it in your models and then decorate your controller functions.
example:
@memcheck
def index():
response.flash = T("Welcome to web2py!")
return dict(message=T('Hello World'))
BEERWARE - You should try to buy Leonel Câmara beers!
"""
from functools import wraps
from collections import Counter, Mapping, Iterable
from gluon.languages import lazyT
from gc import get_objects
def get_value_objects(v):
"""
Generate an object for each value in a value including itself.
"""
if isinstance(v, basestring):
yield v
elif isinstance(v, lazyT):
yield v
yield v.s # Check lazyT symbols dict
for i in v.s:
for new_v in get_value_objects(i):
yield new_v
elif isinstance(v, Mapping):
yield v
for i in v.values():
for new_v in get_value_objects(i):
yield new_v
elif isinstance(v, Iterable):
yield v
for i in v:
for new_v in get_value_objects(i):
yield new_v
else:
yield v
@wraps(f)
def wrapper(*args, **kwargs):
before = Counter(type(obj) for obj in get_objects())
result = f(*args, **kwargs)
after = Counter(type(obj) for obj in get_objects())
result_objs = Counter(type(obj) for obj in get_value_objects(result))
count = after - before - result_objs - Counter([Counter])
# This and other stuff put in the response or session is not a memory
# leak.
# So false positives may appear for what's not accounted here.
if response.flash:
count -= Counter(type(obj) for obj in get_value_objects(response.flash))
if response.js:
count -= Counter(type(obj) for obj in get_value_objects(response.js))
# Finally we are ready to report what we have found.
for k in count:
print 'LEAKED: %d of type %s' % (count[k], k)
return result
return wrapper
--
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
---
You received this message because you are subscribed to the Google Groups "web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to web2py+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
@niplhod do you know if is there a way to integrate memory profiling in travis-ci??
Line # Mem usage Increment Line Contents
================================================
531 28.8945 MiB 0.0000 MiB @profile(precision=4)
532 def run_models_in(environment):
533 """
534 Runs all models (in the app specified by the current folder)
535 It tries pre-compiled models first before compiling them.
536 """
537
538 28.8945 MiB 0.0000 MiB folder = environment['request'].folder
539 28.8945 MiB 0.0000 MiB c = environment['request'].controller
540 #f = environment['request'].function
541 28.8945 MiB 0.0000 MiB response = environment['response']
542
543 28.8945 MiB 0.0000 MiB path = pjoin(folder, 'models')
544 28.8945 MiB 0.0000 MiB cpath = pjoin(folder, 'compiled')
545 28.8945 MiB 0.0000 MiB compiled = os.path.exists(cpath)
546 28.8945 MiB 0.0000 MiB if compiled:
547 models = sorted(listdir(cpath, '^models[_.][\w.]+\.pyc$', 0), model_cmp)
548 else:
549 28.8984 MiB 0.0039 MiB models = sorted(listdir(path, '^\w+\.py$', 0, sort=False), model_cmp_sep)
550 28.8984 MiB 0.0000 MiB models_to_run = None
551 41.7812 MiB 12.8828 MiB for model in models:
552 41.7656 MiB -0.0156 MiB if response.models_to_run != models_to_run:
553 37.3164 MiB -4.4492 MiB regex = models_to_run = response.models_to_run[:]
554 37.3164 MiB 0.0000 MiB if isinstance(regex, list):
555 37.3320 MiB 0.0156 MiB regex = re_compile('|'.join(regex))
556 41.7656 MiB 4.4336 MiB if models_to_run:
557 41.7656 MiB 0.0000 MiB if compiled:
558 n = len(cpath)+8
559 fname = model[n:-4].replace('.','/')+'.py'
560 else:
561 41.7656 MiB 0.0000 MiB n = len(path)+1
562 41.7656 MiB 0.0000 MiB fname = model[n:].replace(os.path.sep,'/')
563 41.7656 MiB 0.0000 MiB if not regex.search(fname) and c != 'appadmin':
564 continue
565 41.7656 MiB 0.0000 MiB elif compiled:
566 code = read_pyc(model)
567 41.7656 MiB 0.0000 MiB elif is_gae:
568 code = getcfs(model, model,
569 lambda: compile2(read_file(model), model))
570 else:
571 41.7656 MiB 0.0000 MiB code = getcfs(model, model, None)
572 41.7812 MiB 0.0156 MiB restricted(code, environment, layer=model)
Line # Mem usage Increment Line Contents
================================================
531 44.2695 MiB 0.0000 MiB @profile(precision=4)
532 def run_models_in(environment):
533 """
534 Runs all models (in the app specified by the current folder)
535 It tries pre-compiled models first before compiling them.
536 """
537
538 44.2695 MiB 0.0000 MiB folder = environment['request'].folder
539 44.2695 MiB 0.0000 MiB c = environment['request'].controller
540 #f = environment['request'].function
541 44.2695 MiB 0.0000 MiB response = environment['response']
542
543 44.2695 MiB 0.0000 MiB path = pjoin(folder, 'models')
544 44.2695 MiB 0.0000 MiB cpath = pjoin(folder, 'compiled')
545 44.2695 MiB 0.0000 MiB compiled = os.path.exists(cpath)
546 44.2695 MiB 0.0000 MiB if compiled:
547 models = sorted(listdir(cpath, '^models[_.][\w.]+\.pyc$', 0), model_cmp)
548 else:
549 44.2734 MiB 0.0039 MiB models = sorted(listdir(path, '^\w+\.py$', 0, sort=False), model_cmp_sep)
550 44.2734 MiB 0.0000 MiB models_to_run = None
551 45.0664 MiB 0.7930 MiB for model in models:
552 45.0625 MiB -0.0039 MiB if response.models_to_run != models_to_run:
553 44.2891 MiB -0.7734 MiB regex = models_to_run = response.models_to_run[:]
554 44.2891 MiB 0.0000 MiB if isinstance(regex, list):
555 44.2891 MiB 0.0000 MiB regex = re_compile('|'.join(regex))
556 45.0625 MiB 0.7734 MiB if models_to_run:
557 45.0625 MiB 0.0000 MiB if compiled:
558 n = len(cpath)+8
559 fname = model[n:-4].replace('.','/')+'.py'
560 else:
561 45.0625 MiB 0.0000 MiB n = len(path)+1
562 45.0625 MiB 0.0000 MiB fname = model[n:].replace(os.path.sep,'/')
563 45.0625 MiB 0.0000 MiB if not regex.search(fname) and c != 'appadmin':
564 continue
565 45.0625 MiB 0.0000 MiB elif compiled:
566 code = read_pyc(model)
567 45.0625 MiB 0.0000 MiB elif is_gae:
568 code = getcfs(model, model,
569 lambda: compile2(read_file(model), model))
570 else:
571 45.0625 MiB 0.0000 MiB code = getcfs(model, model, None)
572 45.0664 MiB 0.0039 MiB restricted(code, environment, layer=model)
...