-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Add a new memleak script that does everything #5360
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 1 commit
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
05c347f
Add a new memleak script that does everything
mdboom 6572456
Fix average increase calculation by tracking peaks
mdboom 7444a98
Better message if running on Python < 3.5
mdboom 457fd94
Fix units as reported by report_memory
mdboom b59627b
Use psutil instead of our home-grown utilities
mdboom File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next
Next commit
Add a new memleak script that does everything
This replaces our 4 memleak scripts with one that is able to test any backend, with or without plot content, and with or without interactive mode. The calculation of average increase per iteration has been fixed. Before, it assumed the increase was monotonically increasing, when in fact it flucuates quite a bit. Therefore, it now calculates the difference between each pair of results and averages that. Also, the results are stored in pre-allocated Numpy arrays rather than Python lists to avoid including the increasing size of the Python lists in the results.
- Loading branch information
commit 05c347f991feb8e43334e5de50005fd8d74916bd
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
#!/usr/bin/env python | ||
|
||
from __future__ import print_function | ||
|
||
import gc | ||
import tracemalloc | ||
|
||
import numpy as np | ||
|
||
|
||
def run_memleak_test(bench, iterations, report): | ||
from matplotlib.cbook import report_memory | ||
|
||
tracemalloc.start() | ||
|
||
starti = min(10, iterations / 2) | ||
endi = iterations | ||
|
||
malloc_arr = np.empty((endi,), dtype=np.int64) | ||
rss_arr = np.empty((endi,), dtype=np.int64) | ||
nobjs_arr = np.empty((endi,), dtype=np.int64) | ||
garbage_arr = np.empty((endi,), dtype=np.int64) | ||
|
||
for i in range(endi): | ||
bench() | ||
|
||
gc.collect() | ||
rss = report_memory() | ||
malloc, peak = tracemalloc.get_traced_memory() | ||
nobjs = len(gc.get_objects()) | ||
garbage = len(gc.garbage) | ||
print("{0: 4d}: pymalloc {1: 10d}, rss {2: 10d}, nobjs {3: 10d}, garbage {4: 10d}".format( | ||
i, malloc, rss, nobjs, garbage)) | ||
|
||
malloc_arr[i] = malloc | ||
rss_arr[i] = rss | ||
nobjs_arr[i] = nobjs | ||
garbage_arr[i] = garbage | ||
|
||
print('Average memory consumed per loop: %1.4f bytes\n' % | ||
(np.sum(rss_arr[starti+1:] - rss_arr[starti:-1]) / float(endi - starti))) | ||
|
||
from matplotlib import pyplot as plt | ||
fig, (ax1, ax2) = plt.subplots(2) | ||
ax3 = ax1.twinx() | ||
ax1.plot(malloc_arr[5:], 'r') | ||
ax3.plot(rss_arr[5:], 'b') | ||
ax1.set_ylabel('pymalloc', color='r') | ||
ax3.set_ylabel('rss', color='b') | ||
|
||
ax4 = ax2.twinx() | ||
ax2.plot(nobjs_arr[5:], 'r') | ||
ax4.plot(garbage_arr[5:], 'b') | ||
ax2.set_ylabel('total objects', color='r') | ||
ax4.set_ylabel('garbage objects', color='b') | ||
|
||
if not report.endswith('.pdf'): | ||
report = report + '.pdf' | ||
fig.savefig(report, format='pdf') | ||
|
||
|
||
class MemleakTest(object): | ||
def __init__(self, empty): | ||
self.empty = empty | ||
|
||
def __call__(self): | ||
import matplotlib.pyplot as plt | ||
|
||
fig = plt.figure(1) | ||
|
||
if not self.empty: | ||
t1 = np.arange(0.0, 2.0, 0.01) | ||
y1 = np.sin(2 * np.pi * t1) | ||
y2 = np.random.rand(len(t1)) | ||
X = np.random.rand(50, 50) | ||
|
||
ax = fig.add_subplot(221) | ||
ax.plot(t1, y1, '-') | ||
ax.plot(t1, y2, 's') | ||
|
||
ax = fig.add_subplot(222) | ||
ax.imshow(X) | ||
|
||
ax = fig.add_subplot(223) | ||
ax.scatter(np.random.rand(50), np.random.rand(50), | ||
s=100 * np.random.rand(50), c=np.random.rand(50)) | ||
|
||
ax = fig.add_subplot(224) | ||
ax.pcolor(10 * np.random.rand(50, 50)) | ||
|
||
fig.savefig('tmp', dpi=75) | ||
plt.close(1) | ||
|
||
|
||
if __name__ == '__main__': | ||
import argparse | ||
|
||
parser = argparse.ArgumentParser('Run memory leak tests') | ||
parser.add_argument('backend', type=str, nargs=1, | ||
help='backend to test') | ||
parser.add_argument('iterations', type=int, nargs=1, | ||
help='number of iterations') | ||
parser.add_argument('report', type=str, nargs=1, | ||
help='filename to save report') | ||
parser.add_argument('--empty', action='store_true', | ||
help="Don't plot any content, just test creating " | ||
"and destroying figures") | ||
parser.add_argument('--interactive', action='store_true', | ||
help="Turn on interactive mode to actually open " | ||
"windows. Only works with some GUI backends.") | ||
|
||
|
||
args = parser.parse_args() | ||
|
||
import matplotlib | ||
matplotlib.use(args.backend[0]) | ||
|
||
if args.interactive: | ||
from matplotlib import pyplot as plt | ||
plt.ion() | ||
|
||
run_memleak_test(MemleakTest(args.empty), args.iterations[0], args.report[0]) |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like just the sum of the differences, which is the end value minus the start value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose that's true. We need a different mechanism, then -- something that will take into account the spikiness of the data. If you select the start and end points incorrectly here you get wildly different results.