1 | ;
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.MemoryLeakDetector = exports.FunctionCpuUsage = exports.FunctionStatsMap = exports.FactoryMap = void 0;
|
4 | const provider_1 = require("./provider");
|
5 | const shared_1 = require("./shared");
|
6 | class FactoryMap extends Map {
|
7 | constructor(factory) {
|
8 | super();
|
9 | this.factory = factory;
|
10 | }
|
11 | getOrCreate(key) {
|
12 | let val = this.get(key);
|
13 | if (!val) {
|
14 | val = this.factory(key);
|
15 | this.set(key, val);
|
16 | }
|
17 | return val;
|
18 | }
|
19 | }
|
20 | exports.FactoryMap = FactoryMap;
|
21 | class FunctionStatsMap {
|
22 | constructor() {
|
23 | this.fIncremental = new FactoryMap(() => new provider_1.FunctionStats());
|
24 | this.fAggregate = new FactoryMap(() => new provider_1.FunctionStats());
|
25 | this.aggregate = new provider_1.FunctionStats();
|
26 | }
|
27 | update(fn, key, value) {
|
28 | this.fIncremental.getOrCreate(fn)[key].update(value);
|
29 | this.fAggregate.getOrCreate(fn)[key].update(value);
|
30 | this.aggregate[key].update(value);
|
31 | }
|
32 | incr(fn, key, n = 1) {
|
33 | this.fIncremental.getOrCreate(fn)[key] += n;
|
34 | this.fAggregate.getOrCreate(fn)[key] += n;
|
35 | this.aggregate[key] += n;
|
36 | }
|
37 | resetIncremental() {
|
38 | this.fIncremental.clear();
|
39 | }
|
40 | toString() {
|
41 | return [...this.fAggregate].map(([key, value]) => `[${key}] ${value}`).join("\n");
|
42 | }
|
43 | clear() {
|
44 | this.fIncremental.clear();
|
45 | this.fAggregate.clear();
|
46 | }
|
47 | }
|
48 | exports.FunctionStatsMap = FunctionStatsMap;
|
49 | class FunctionCpuUsage {
|
50 | constructor() {
|
51 | this.utime = new shared_1.Statistics();
|
52 | this.stime = new shared_1.Statistics();
|
53 | this.cpuTime = new shared_1.Statistics();
|
54 | this.smallest = new shared_1.SmallestN(100);
|
55 | }
|
56 | }
|
57 | exports.FunctionCpuUsage = FunctionCpuUsage;
|
58 | class FunctionMemoryStats {
|
59 | constructor() {
|
60 | this.rss = new shared_1.Statistics();
|
61 | this.heapTotal = new shared_1.Statistics();
|
62 | this.heapUsed = new shared_1.Statistics();
|
63 | this.external = new shared_1.Statistics();
|
64 | }
|
65 | }
|
66 | class FunctionMemoryCounters {
|
67 | constructor() {
|
68 | this.heapUsedGrowth = 0;
|
69 | this.externalGrowth = 0;
|
70 | }
|
71 | }
|
72 | class MemoryLeakDetector {
|
73 | constructor(memorySize) {
|
74 | this.instances = new FactoryMap(() => new FunctionMemoryStats());
|
75 | this.counters = new FactoryMap(() => new FunctionMemoryCounters());
|
76 | this.warned = new Set();
|
77 | this.memorySize = memorySize || 100;
|
78 | }
|
79 | detectedNewLeak(fn, instanceId, memoryUsage) {
|
80 | if (this.warned.has(fn)) {
|
81 | return false;
|
82 | }
|
83 | const { rss, heapTotal, heapUsed, external } = memoryUsage;
|
84 | const instanceStats = this.instances.getOrCreate(instanceId);
|
85 | const counters = this.counters.getOrCreate(instanceId);
|
86 | if (heapUsed > instanceStats.heapUsed.max) {
|
87 | counters.heapUsedGrowth++;
|
88 | }
|
89 | else {
|
90 | counters.heapUsedGrowth = 0;
|
91 | }
|
92 | if (external > instanceStats.external.max) {
|
93 | counters.externalGrowth++;
|
94 | }
|
95 | else {
|
96 | counters.externalGrowth = 0;
|
97 | }
|
98 | instanceStats.rss.update(rss);
|
99 | instanceStats.heapTotal.update(heapTotal);
|
100 | instanceStats.heapUsed.update(heapUsed);
|
101 | instanceStats.external.update(external);
|
102 | if (heapUsed > this.memorySize * 0.8 * 2 ** 20 ||
|
103 | external > this.memorySize * 0.8 * 2 ** 20) {
|
104 | if (counters.heapUsedGrowth > 4 || counters.externalGrowth > 4) {
|
105 | this.warned.add(fn);
|
106 | return true;
|
107 | }
|
108 | }
|
109 | return false;
|
110 | }
|
111 | clear() {
|
112 | this.instances.clear();
|
113 | this.counters.clear();
|
114 | this.warned.clear();
|
115 | }
|
116 | }
|
117 | exports.MemoryLeakDetector = MemoryLeakDetector;
|
118 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWV0cmljcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9tZXRyaWNzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHlDQUEyQztBQUMzQyxxQ0FBaUQ7QUFHakQsTUFBYSxVQUErQixTQUFRLEdBQVM7SUFDekQsWUFBcUIsT0FBc0I7UUFDdkMsS0FBSyxFQUFFLENBQUM7UUFEUyxZQUFPLEdBQVAsT0FBTyxDQUFlO0lBRTNDLENBQUM7SUFFRCxXQUFXLENBQUMsR0FBTTtRQUNkLElBQUksR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDeEIsSUFBSSxDQUFDLEdBQUcsRUFBRTtZQUNOLEdBQUcsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ3hCLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1NBQ3RCO1FBQ0QsT0FBTyxHQUFHLENBQUM7SUFDZixDQUFDO0NBQ0o7QUFiRCxnQ0FhQztBQUVELE1BQWEsZ0JBQWdCO0lBQTdCO1FBQ0ksaUJBQVksR0FBRyxJQUFJLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLHdCQUFhLEVBQUUsQ0FBQyxDQUFDO1FBQ3pELGVBQVUsR0FBRyxJQUFJLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLHdCQUFhLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZELGNBQVMsR0FBRyxJQUFJLHdCQUFhLEVBQUUsQ0FBQztJQThCcEMsQ0FBQztJQTVCRyxNQUFNLENBQ0YsRUFBVSxFQUNWLEdBQXNELEVBQ3RELEtBQWE7UUFFYixJQUFJLENBQUMsWUFBWSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDckQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFD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QixJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQ3hCLENBQUM7Q0FDSjtBQWpERCxnREFpREMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBGdW5jdGlvblN0YXRzIH0gZnJvbSBcIi4vcHJvdmlkZXJcIjtcbmltcG9ydCB7IFNtYWxsZXN0TiwgU3RhdGlzdGljcyB9IGZyb20gXCIuL3NoYXJlZFwiO1xuaW1wb3J0IHsgUHJvcGVydGllc09mVHlwZSB9IGZyb20gXCIuL3R5cGVzXCI7XG5cbmV4cG9ydCBjbGFzcyBGYWN0b3J5TWFwPEsgPSBzdHJpbmcsIFYgPSB7fT4gZXh0ZW5kcyBNYXA8SywgVj4ge1xuICAgIGNvbnN0cnVjdG9yKHJlYWRvbmx5IGZhY3Rvcnk6IChrZXk6IEspID0+IFYpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICBnZXRPckNyZWF0ZShrZXk6IEspIHtcbiAgICAgICAgbGV0IHZhbCA9IHRoaXMuZ2V0KGtleSk7XG4gICAgICAgIGlmICghdmFsKSB7XG4gICAgICAgICAgICB2YWwgPSB0aGlzLmZhY3Rvcnkoa2V5KTtcbiAgICAgICAgICAgIHRoaXMuc2V0KGtleSwgdmFsKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdmFsO1xuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIEZ1bmN0aW9uU3RhdHNNYXAge1xuICAgIGZJbmNyZW1lbnRhbCA9IG5ldyBGYWN0b3J5TWFwKCgpID0+IG5ldyBGdW5jdGlvblN0YXRzKCkpO1xuICAgIGZBZ2dyZWdhdGUgPSBuZXcgRmFjdG9yeU1hcCgoKSA9PiBuZXcgRnVuY3Rpb25TdGF0cygpKTtcbiAgICBhZ2dyZWdhdGUgPSBuZXcgRnVuY3Rpb25TdGF0cygpO1xuXG4gICAgdXBkYXRlKFxuICAgICAgICBmbjogc3RyaW5nLFxuICAgICAgICBrZXk6IGtleW9mIFByb3BlcnRpZXNPZlR5cGU8RnVuY3Rpb25TdGF0cywgU3RhdGlzdGljcz4sXG4gICAgICAgIHZhbHVlOiBudW1iZXJcbiAgICApIHtcbiAgICAgICAgdGhpcy5mSW5jcmVtZW50YWwuZ2V0T3JDcmVhdGUoZm4pW2tleV0udXBkYXRlKHZhbHVlKTtcbiAgICAgICAgdGhpcy5mQWdncmVnYXRlLmdldE9yQ3JlYXRlKGZuKVtrZXldLnVwZGF0ZSh2YWx1ZSk7XG4gICAgICAgIHRoaXMuYWdncmVnYXRlW2tleV0udXBkYXRlKHZhbHVlKTtcbiAgICB9XG5cbiAgICBpbmNyKGZuOiBzdHJpbmcsIGtleToga2V5b2YgUHJvcGVydGllc09mVHlwZTxGdW5jdGlvblN0YXRzLCBudW1iZXI+LCBuOiBudW1iZXIgPSAxKSB7XG4gICAgICAgIHRoaXMuZkluY3JlbWVudGFsLmdldE9yQ3JlYXRlKGZuKVtrZXldICs9IG47XG4gICAgICAgIHRoaXMuZkFnZ3JlZ2F0ZS5nZXRPckNyZWF0ZShmbilba2V5XSArPSBuO1xuICAgICAgICB0aGlzLmFnZ3JlZ2F0ZVtrZXldICs9IG47XG4gICAgfVxuXG4gICAgcmVzZXRJbmNyZW1lbnRhbCgpIHtcbiAgICAgICAgdGhpcy5mSW5jcmVtZW50YWwuY2xlYXIoKTtcbiAgICB9XG5cbiAgICB0b1N0cmluZygpIHtcbiAgICAgICAgcmV0dXJuIFsuLi50aGlzLmZBZ2dyZWdhdGVdLm1hcCgoW2tleSwgdmFsdWVdKSA9PiBgWyR7a2V5fV0gJHt2YWx1ZX1gKS5qb2luKFwiXFxuXCIpO1xuICAgIH1cblxuICAgIGNsZWFyKCkge1xuICAgICAgICB0aGlzLmZJbmNyZW1lbnRhbC5jbGVhcigpO1xuICAgICAgICB0aGlzLmZBZ2dyZWdhdGUuY2xlYXIoKTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBGdW5jdGlvbkNwdVVzYWdlIHtcbiAgICB1dGltZSA9IG5ldyBTdGF0aXN0aWNzKCk7XG4gICAgc3RpbWUgPSBuZXcgU3RhdGlzdGljcygpO1xuICAgIGNwdVRpbWUgPSBuZXcgU3RhdGlzdGljcygpO1xuICAgIHNtYWxsZXN0ID0gbmV3IFNtYWxsZXN0TigxMDApO1xufVxuXG5jbGFzcyBGdW5jdGlvbk1lbW9yeVN0YXRzIHtcbiAgICByc3MgPSBuZXcgU3RhdGlzdGljcygpO1xuICAgIGhlYXBUb3RhbCA9IG5ldyBTdGF0aXN0aWNzKCk7XG4gICAgaGVhcFVzZWQgPSBuZXcgU3RhdGlzdGljcygpO1xuICAgIGV4dGVybmFsID0gbmV3IFN0YXRpc3RpY3MoKTtcbn1cblxuY2xhc3MgRnVuY3Rpb25NZW1vcnlDb3VudGVycyB7XG4gICAgaGVhcFVzZWRHcm93dGggPSAwO1xuICAgIGV4dGVybmFsR3Jvd3RoID0gMDtcbn1cblxuZXhwb3J0IGNsYXNzIE1lbW9yeUxlYWtEZXRlY3RvciB7XG4gICAgcHJpdmF0ZSBpbnN0YW5jZXMgPSBuZXcgRmFjdG9yeU1hcCgoKSA9PiBuZXcgRnVuY3Rpb25NZW1vcnlTdGF0cygpKTtcbiAgICBwcml2YXRlIGNvdW50ZXJzID0gbmV3IEZhY3RvcnlNYXAoKCkgPT4gbmV3IEZ1bmN0aW9uTWVtb3J5Q291bnRlcnMoKSk7XG4gICAgcHJpdmF0ZSB3YXJuZWQgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICBwcml2YXRlIG1lbW9yeVNpemU6IG51bWJlcjtcblxuICAgIGNvbnN0cnVjdG9yKG1lbW9yeVNpemU/OiBudW1iZXIpIHtcbiAgICAgICAgdGhpcy5tZW1vcnlTaXplID0gbWVtb3J5U2l6ZSB8fCAxMDA7XG4gICAgfVxuXG4gICAgZGV0ZWN0ZWROZXdMZWFrKGZuOiBzdHJpbmcsIGluc3RhbmNlSWQ6IHN0cmluZywgbWVtb3J5VXNhZ2U6IE5vZGVKUy5NZW1vcnlVc2FnZSkge1xuICAgICAgICBpZiAodGhpcy53YXJuZWQuaGFzKGZuKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHsgcnNzLCBoZWFwVG90YWwsIGhlYXBVc2VkLCBleHRlcm5hbCB9ID0gbWVtb3J5VXNhZ2U7XG4gICAgICAgIGNvbnN0IGluc3RhbmNlU3RhdHMgPSB0aGlzLmluc3RhbmNlcy5nZXRPckNyZWF0ZShpbnN0YW5jZUlkKTtcbiAgICAgICAgY29uc3QgY291bnRlcnMgPSB0aGlzLmNvdW50ZXJzLmdldE9yQ3JlYXRlKGluc3RhbmNlSWQpO1xuICAgICAgICBpZiAoaGVhcFVzZWQgPiBpbnN0YW5jZVN0YXRzLmhlYXBVc2VkLm1heCkge1xuICAgICAgICAgICAgY291bnRlcnMuaGVhcFVzZWRHcm93dGgrKztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvdW50ZXJzLmhlYXBVc2VkR3Jvd3RoID0gMDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZXh0ZXJuYWwgPiBpbnN0YW5jZVN0YXRzLmV4dGVybmFsLm1heCkge1xuICAgICAgICAgICAgY291bnRlcnMuZXh0ZXJuYWxHcm93dGgrKztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvdW50ZXJzLmV4dGVybmFsR3Jvd3RoID0gMDtcbiAgICAgICAgfVxuICAgICAgICBpbnN0YW5jZVN0YXRzLnJzcy51cGRhdGUocnNzKTtcbiAgICAgICAgaW5zdGFuY2VTdGF0cy5oZWFwVG90YWwudXBkYXRlKGhlYXBUb3RhbCk7XG4gICAgICAgIGluc3RhbmNlU3RhdHMuaGVhcFVzZWQudXBkYXRlKGhlYXBVc2VkKTtcbiAgICAgICAgaW5zdGFuY2VTdGF0cy5leHRlcm5hbC51cGRhdGUoZXh0ZXJuYWwpO1xuXG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIGhlYXBVc2VkID4gdGhpcy5tZW1vcnlTaXplICogMC44ICogMiAqKiAyMCB8fFxuICAgICAgICAgICAgZXh0ZXJuYWwgPiB0aGlzLm1lbW9yeVNpemUgKiAwLjggKiAyICoqIDIwXG4gICAgICAgICkge1xuICAgICAgICAgICAgaWYgKGNvdW50ZXJzLmhlYXBVc2VkR3Jvd3RoID4gNCB8fCBjb3VudGVycy5leHRlcm5hbEdyb3d0aCA+IDQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLndhcm5lZC5hZGQoZm4pO1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBjbGVhcigpIHtcbiAgICAgICAgdGhpcy5pbnN0YW5jZXMuY2xlYXIoKTtcbiAgICAgICAgdGhpcy5jb3VudGVycy5jbGVhcigpO1xuICAgICAgICB0aGlzLndhcm5lZC5jbGVhcigpO1xuICAgIH1cbn1cbiJdfQ== |
\ | No newline at end of file |