memory-monitoring.ts•33.5 kB
/**
* Real-Time Memory Monitoring System for GEPA
*
* Comprehensive memory monitoring that integrates leak detection, GC optimization,
* and performance tracking to provide live visualization, alerts, and analytics.
*/
import { EventEmitter } from 'events';
import { PerformanceTracker } from '../services/performance-tracker';
import { MemoryLeakDetector, MemoryLeakDetection } from './memory-leak-detector';
import { GarbageCollectionOptimizer, GCMetrics } from './gc-optimizer';
/**
* Real-time monitoring configuration
*/
export interface MemoryMonitoringConfig {
/** Monitoring update interval (ms) */
updateInterval: number;
/** History retention window (ms) */
historyWindow: number;
/** Maximum data points to retain */
maxDataPoints: number;
/** Alert threshold configuration */
alertThresholds: {
memoryUsagePercent: number;
heapGrowthRate: number;
gcFrequency: number;
leakSeverity: 'low' | 'medium' | 'high' | 'critical';
};
/** Dashboard configuration */
dashboard: {
enabled: boolean;
updateRate: number;
components: string[];
};
/** Notification settings */
notifications: {
enabled: boolean;
channels: ('console' | 'file' | 'webhook')[];
escalationPolicy: {
enabled: boolean;
levels: number;
delayBetweenLevels: number;
};
};
}
/**
* Real-time memory snapshot
*/
export interface MemorySnapshot {
timestamp: number;
system: {
rss: number;
heapTotal: number;
heapUsed: number;
heapFree: number;
external: number;
arrayBuffers: number;
};
components: {
[componentName: string]: {
objectCount: number;
memoryUsage: number;
growthRate: number;
poolUtilization: number;
};
};
gcMetrics: {
lastGCTime: number;
lastGCDuration: number;
lastGCType: string;
gcFrequency: number;
totalCollections: number;
};
alerts: MemoryAlert[];
}
/**
* Memory usage trend analysis
*/
export interface MemoryTrend {
component: string;
metric: string;
trend: 'increasing' | 'decreasing' | 'stable' | 'volatile';
slope: number;
confidence: number;
projection: {
nextHour: number;
nextDay: number;
thresholdReach?: number;
};
}
/**
* Memory alert definition
*/
export interface MemoryAlert {
id: string;
timestamp: number;
severity: 'low' | 'medium' | 'high' | 'critical';
type: 'threshold' | 'leak' | 'gc' | 'trend' | 'anomaly';
component: string;
message: string;
currentValue: number;
threshold?: number;
recommendation: string;
autoFixAvailable: boolean;
acknowledged: boolean;
resolvedAt?: number;
}
/**
* Memory hotspot identification
*/
export interface MemoryHotspot {
component: string;
type: 'allocation' | 'retention' | 'growth' | 'fragmentation';
severity: number;
impact: {
memoryUsage: number;
performance: number;
stability: number;
};
patterns: {
allocationFrequency: number;
averageObjectSize: number;
retentionTime: number;
};
recommendations: string[];
}
/**
* Performance impact analysis
*/
export interface PerformanceImpact {
memoryPressure: {
level: 'low' | 'medium' | 'high' | 'critical';
impact: number;
affectedOperations: string[];
};
gcImpact: {
pauseTimeImpact: number;
throughputImpact: number;
latencyImpact: number;
};
optimizationOpportunities: {
category: string;
potential: number;
effort: 'low' | 'medium' | 'high';
description: string;
}[];
}
/**
* Memory monitoring report
*/
export interface MemoryReport {
timestamp: number;
summary: {
overallHealth: 'healthy' | 'warning' | 'critical';
memoryEfficiency: number;
leakRisk: number;
performanceImpact: number;
};
trends: MemoryTrend[];
hotspots: MemoryHotspot[];
alerts: MemoryAlert[];
recommendations: {
immediate: string[];
shortTerm: string[];
longTerm: string[];
};
metrics: {
snapshots: MemorySnapshot[];
historicalData: any;
};
}
/**
* Live memory monitoring dashboard data
*/
export interface DashboardData {
timestamp: number;
overview: {
totalMemory: number;
usedMemory: number;
freeMemory: number;
memoryPressure: number;
alertCount: number;
};
components: {
name: string;
memoryUsage: number;
trend: 'up' | 'down' | 'stable';
status: 'healthy' | 'warning' | 'critical';
objectCount: number;
growthRate: number;
}[];
charts: {
memoryUsage: { timestamp: number; value: number }[];
gcActivity: { timestamp: number; duration: number; type: string }[];
leakDetection: { timestamp: number; severity: string; component: string }[];
performance: { timestamp: number; metric: string; value: number }[];
};
recentAlerts: MemoryAlert[];
}
/**
* Main Real-Time Memory Monitoring System
*/
export class MemoryMonitoringSystem extends EventEmitter {
private config: MemoryMonitoringConfig;
private leakDetector: MemoryLeakDetector;
private gcOptimizer: GarbageCollectionOptimizer;
private isMonitoring = false;
private monitoringInterval?: ReturnType<typeof setInterval>;
private dashboardInterval?: ReturnType<typeof setInterval>;
// Monitoring state
private snapshots: MemorySnapshot[] = [];
private alerts: Map<string, MemoryAlert> = new Map();
private trends: Map<string, MemoryTrend> = new Map();
private hotspots: Map<string, MemoryHotspot> = new Map();
// Alert state
private alertCounts = new Map<string, number>();
constructor(
config: Partial<MemoryMonitoringConfig>,
_performanceTracker: PerformanceTracker,
leakDetector: MemoryLeakDetector,
gcOptimizer: GarbageCollectionOptimizer
) {
super();
this.config = {
updateInterval: config.updateInterval || 5000,
historyWindow: config.historyWindow || 3600000, // 1 hour
maxDataPoints: config.maxDataPoints || 720, // 1 hour at 5s intervals
alertThresholds: {
memoryUsagePercent: 80,
heapGrowthRate: 10 * 1024 * 1024, // 10MB/min
gcFrequency: 10, // per minute
leakSeverity: 'medium',
...config.alertThresholds
},
dashboard: {
enabled: true,
updateRate: 2000,
components: ['evolution-engine', 'pareto-frontier', 'cache-manager', 'llm-adapter'],
...config.dashboard
},
notifications: {
enabled: true,
channels: ['console'],
escalationPolicy: {
enabled: true,
levels: 3,
delayBetweenLevels: 300000, // 5 minutes
},
...config.notifications
}
};
this.leakDetector = leakDetector;
this.gcOptimizer = gcOptimizer;
this.setupEventHandlers();
}
/**
* Start real-time memory monitoring
*/
startMonitoring(): void {
if (this.isMonitoring) {
// eslint-disable-next-line no-console
console.warn('Memory monitoring is already active');
return;
}
this.isMonitoring = true;
this.emit('monitoringStarted');
// Start main monitoring loop
this.monitoringInterval = setInterval(() => {
this.collectSnapshot();
}, this.config.updateInterval);
// Start dashboard updates if enabled
if (this.config.dashboard.enabled) {
this.dashboardInterval = setInterval(() => {
this.updateDashboard();
}, this.config.dashboard.updateRate);
}
// eslint-disable-next-line no-console
console.log(`Memory monitoring started - update interval: ${this.config.updateInterval}ms`);
}
/**
* Stop memory monitoring
*/
stopMonitoring(): void {
this.isMonitoring = false;
if (this.monitoringInterval) {
clearInterval(this.monitoringInterval);
this.monitoringInterval = undefined as any;
}
if (this.dashboardInterval) {
clearInterval(this.dashboardInterval);
this.dashboardInterval = undefined as any;
}
this.emit('monitoringStopped');
// eslint-disable-next-line no-console
console.log('Memory monitoring stopped');
}
/**
* Collect real-time memory snapshot
*/
private async collectSnapshot(): Promise<void> {
try {
const timestamp = Date.now();
const memoryUsage = process.memoryUsage();
// Get component memory data
const leakStats = this.leakDetector.getStatistics();
const gcStats = this.gcOptimizer.getOptimizationStatistics();
// Build component metrics
const components: any = {};
for (const component of leakStats.components) {
const componentPrefix = component.name.split('-')[0];
const poolStats = componentPrefix ? gcStats.objectPools.find(p =>
p.name.includes(componentPrefix)
) : undefined;
components[component.name] = {
objectCount: component.objectCount,
memoryUsage: component.memoryUsage,
growthRate: component.growthRate,
poolUtilization: poolStats?.utilizationRate || 0
};
}
// Create snapshot
const snapshot: MemorySnapshot = {
timestamp,
system: {
rss: memoryUsage.rss,
heapTotal: memoryUsage.heapTotal,
heapUsed: memoryUsage.heapUsed,
heapFree: memoryUsage.heapTotal - memoryUsage.heapUsed,
external: memoryUsage.external,
arrayBuffers: memoryUsage.arrayBuffers
},
components,
gcMetrics: {
lastGCTime: timestamp, // Would be from actual GC events
lastGCDuration: 0,
lastGCType: 'unknown',
gcFrequency: gcStats.gcMetrics.totalCollections,
totalCollections: gcStats.gcMetrics.totalCollections
},
alerts: Array.from(this.alerts.values())
};
// Store snapshot
this.snapshots.push(snapshot);
// Maintain history window
this.maintainHistoryWindow();
// Analyze trends and detect issues
await this.analyzeSnapshot(snapshot);
// Emit real-time update
this.emit('snapshot', snapshot);
} catch (error) {
this.emit('monitoringError', error);
// eslint-disable-next-line no-console
console.error('Error collecting memory snapshot:', error);
}
}
/**
* Analyze snapshot for trends and issues
*/
private async analyzeSnapshot(snapshot: MemorySnapshot): Promise<void> {
// Update trends
this.updateTrends(snapshot);
// Check alert thresholds
await this.checkAlertThresholds(snapshot);
// Identify hotspots
this.identifyHotspots(snapshot);
// Analyze performance impact
this.analyzePerformanceImpact(snapshot);
}
/**
* Update memory trends
*/
private updateTrends(snapshot: MemorySnapshot): void {
const recentSnapshots = this.snapshots.slice(-10);
if (recentSnapshots.length < 3) return;
// Analyze system memory trend
const heapUsages = recentSnapshots.map(s => s.system.heapUsed);
const systemTrend = this.calculateTrend('system', 'heapUsed', heapUsages);
this.trends.set('system-heap', systemTrend);
// Analyze component trends
for (const [componentName] of Object.entries(snapshot.components)) {
const componentUsages = recentSnapshots.map(s =>
s.components[componentName]?.memoryUsage || 0
);
const trend = this.calculateTrend(componentName, 'memoryUsage', componentUsages);
this.trends.set(`${componentName}-memory`, trend);
}
}
/**
* Calculate trend analysis
*/
private calculateTrend(component: string, metric: string, values: number[]): MemoryTrend {
if (values.length < 3) {
return {
component,
metric,
trend: 'stable',
slope: 0,
confidence: 0,
projection: { nextHour: values[values.length - 1] || 0, nextDay: values[values.length - 1] || 0 }
};
}
// Linear regression
const n = values.length;
const sumX = values.reduce((sum, _, i) => sum + i, 0);
const sumY = values.reduce((sum, val) => sum + val, 0);
const sumXY = values.reduce((sum, val, i) => sum + (i * val), 0);
const sumXX = values.reduce((sum, _, i) => sum + (i * i), 0);
const slope = (n * sumXY - sumX * sumY) / (n * sumXX - sumX * sumX) || 0;
// Calculate confidence (correlation coefficient)
const meanX = sumX / n;
const meanY = sumY / n;
const numerator = values.reduce((sum, val, i) => sum + (i - meanX) * (val - meanY), 0);
const denomX = Math.sqrt(values.reduce((sum, _, i) => sum + Math.pow(i - meanX, 2), 0));
const denomY = Math.sqrt(values.reduce((sum, val) => sum + Math.pow(val - meanY, 2), 0));
const confidence = denomX && denomY ? Math.abs(numerator / (denomX * denomY)) : 0;
// Determine trend direction
let trend: 'increasing' | 'decreasing' | 'stable' | 'volatile';
const threshold = Math.abs(slope) > (meanY * 0.05); // 5% change threshold
if (!threshold) {
trend = 'stable';
} else if (slope > 0) {
trend = 'increasing';
} else {
trend = 'decreasing';
}
// Check for volatility
const variance = values.reduce((sum, val) => sum + Math.pow(val - meanY, 2), 0) / n;
const stdDev = Math.sqrt(variance);
if (stdDev > meanY * 0.2) { // High variance
trend = 'volatile';
}
// Project future values
const currentValue = values[values.length - 1];
if (currentValue === undefined) {
return {
component,
metric,
trend: 'stable' as const,
slope: 0,
confidence: 0,
projection: {
nextHour: 0,
nextDay: 0,
thresholdReach: 0
}
};
}
const hourProjection = currentValue + (slope * 720); // 720 intervals in 1 hour
const dayProjection = currentValue + (slope * 17280); // 17280 intervals in 1 day
return {
component,
metric,
trend,
slope,
confidence,
projection: {
nextHour: Math.max(0, hourProjection),
nextDay: Math.max(0, dayProjection)
}
};
}
/**
* Check alert thresholds
*/
private async checkAlertThresholds(snapshot: MemorySnapshot): Promise<void> {
// Check system memory thresholds
const heapUsagePercent = (snapshot.system.heapUsed / snapshot.system.heapTotal) * 100;
if (heapUsagePercent > this.config.alertThresholds.memoryUsagePercent) {
await this.createAlert({
type: 'threshold',
severity: heapUsagePercent > 95 ? 'critical' : 'high',
component: 'system',
message: `High heap usage: ${heapUsagePercent.toFixed(1)}%`,
currentValue: heapUsagePercent,
threshold: this.config.alertThresholds.memoryUsagePercent,
recommendation: 'Consider triggering garbage collection or reducing memory allocation',
autoFixAvailable: true
});
}
// Check component growth rates
for (const [componentName, componentData] of Object.entries(snapshot.components)) {
if (componentData.growthRate > this.config.alertThresholds.heapGrowthRate) {
await this.createAlert({
type: 'trend',
severity: 'medium',
component: componentName,
message: `High memory growth rate: ${(componentData.growthRate / 1024 / 1024).toFixed(2)} MB/min`,
currentValue: componentData.growthRate,
threshold: this.config.alertThresholds.heapGrowthRate,
recommendation: `Investigate ${componentName} for potential memory leaks`,
autoFixAvailable: false
});
}
}
// Check for memory leaks
const leakDetections = this.leakDetector.getStatistics().recentDetections;
for (const detection of leakDetections) {
if (this.shouldAlertForLeak(detection)) {
await this.createAlert({
type: 'leak',
severity: detection.severity,
component: detection.component,
message: `Memory leak detected: ${detection.leakType}`,
currentValue: detection.currentUsage,
recommendation: detection.recommendation,
autoFixAvailable: detection.autoFixAvailable
});
}
}
}
/**
* Create and manage alerts
*/
private async createAlert(alertData: Partial<MemoryAlert>): Promise<void> {
const alertId = `${alertData.component}-${alertData.type}-${Date.now()}`;
const alert: MemoryAlert = {
id: alertId,
timestamp: Date.now(),
severity: alertData.severity || 'medium',
type: alertData.type || 'threshold',
component: alertData.component || 'unknown',
message: alertData.message || 'Memory alert',
currentValue: alertData.currentValue || 0,
...(alertData.threshold !== undefined ? { threshold: alertData.threshold } : {}),
recommendation: alertData.recommendation || 'Monitor memory usage',
autoFixAvailable: alertData.autoFixAvailable || false,
acknowledged: false
};
this.alerts.set(alertId, alert);
// Handle notifications and escalation
await this.handleAlertNotification(alert);
// Attempt auto-fix if available
if (alert.autoFixAvailable) {
await this.attemptAutoFix(alert);
}
this.emit('alert', alert);
}
/**
* Identify memory hotspots
*/
private identifyHotspots(snapshot: MemorySnapshot): void {
for (const [componentName, componentData] of Object.entries(snapshot.components)) {
// Calculate severity based on multiple factors
const memoryScore = Math.min(componentData.memoryUsage / (100 * 1024 * 1024), 1); // 100MB max
const growthScore = Math.min(Math.abs(componentData.growthRate) / (10 * 1024 * 1024), 1); // 10MB/min max
const utilizationScore = componentData.poolUtilization;
const severity = (memoryScore * 0.4 + growthScore * 0.4 + utilizationScore * 0.2);
if (severity > 0.6) { // High severity threshold
const hotspot: MemoryHotspot = {
component: componentName,
type: this.determineHotspotType(componentData),
severity,
impact: {
memoryUsage: memoryScore,
performance: Math.min(severity * 1.2, 1),
stability: Math.min(growthScore * 1.5, 1)
},
patterns: {
allocationFrequency: componentData.objectCount / 1000, // per second estimate
averageObjectSize: componentData.objectCount > 0 ? componentData.memoryUsage / componentData.objectCount : 0,
retentionTime: 0 // Would need tracking over time
},
recommendations: this.generateHotspotRecommendations(componentName, componentData, severity)
};
this.hotspots.set(componentName, hotspot);
}
}
}
/**
* Determine hotspot type based on component data
*/
private determineHotspotType(componentData: any): 'allocation' | 'retention' | 'growth' | 'fragmentation' {
if (componentData.growthRate > 5 * 1024 * 1024) return 'growth';
if (componentData.objectCount > 50000) return 'allocation';
if (componentData.poolUtilization > 0.9) return 'retention';
return 'fragmentation';
}
/**
* Generate hotspot recommendations
*/
private generateHotspotRecommendations(componentName: string, componentData: any, severity: number): string[] {
const recommendations: string[] = [];
if (componentData.growthRate > 0) {
recommendations.push(`Reduce memory allocation rate in ${componentName}`);
}
if (componentData.poolUtilization > 0.8) {
recommendations.push(`Increase object pool size for ${componentName}`);
}
if (componentData.objectCount > 10000) {
recommendations.push(`Implement object cleanup strategy for ${componentName}`);
}
if (severity > 0.8) {
recommendations.push(`Consider architectural changes for ${componentName}`);
}
return recommendations;
}
/**
* Analyze performance impact
*/
private analyzePerformanceImpact(snapshot: MemorySnapshot): void {
const heapUsageRatio = snapshot.system.heapUsed / snapshot.system.heapTotal;
let pressureLevel: 'low' | 'medium' | 'high' | 'critical';
if (heapUsageRatio > 0.9) pressureLevel = 'critical';
else if (heapUsageRatio > 0.8) pressureLevel = 'high';
else if (heapUsageRatio > 0.6) pressureLevel = 'medium';
else pressureLevel = 'low';
// Emit performance impact analysis
this.emit('performanceImpact', {
memoryPressure: {
level: pressureLevel,
impact: heapUsageRatio,
affectedOperations: this.getAffectedOperations(pressureLevel)
},
gcImpact: {
pauseTimeImpact: this.estimateGCImpact(snapshot),
throughputImpact: heapUsageRatio * 0.3,
latencyImpact: heapUsageRatio * 0.2
}
});
}
/**
* Generate comprehensive memory report
*/
generateReport(): MemoryReport {
const latestSnapshot = this.snapshots[this.snapshots.length - 1];
if (!latestSnapshot) {
throw new Error('No memory snapshots available');
}
// Calculate overall health
const alertCount = Array.from(this.alerts.values()).filter(a => !a.acknowledged).length;
const criticalAlerts = Array.from(this.alerts.values()).filter(a => a.severity === 'critical').length;
let overallHealth: 'healthy' | 'warning' | 'critical';
if (criticalAlerts > 0) overallHealth = 'critical';
else if (alertCount > 5) overallHealth = 'warning';
else overallHealth = 'healthy';
// Calculate efficiency metrics
const heapEfficiency = 1 - (latestSnapshot.system.heapUsed / latestSnapshot.system.heapTotal);
const leakRisk = this.calculateLeakRisk();
const performanceImpact = this.calculatePerformanceImpact();
return {
timestamp: Date.now(),
summary: {
overallHealth,
memoryEfficiency: heapEfficiency,
leakRisk,
performanceImpact
},
trends: Array.from(this.trends.values()),
hotspots: Array.from(this.hotspots.values()),
alerts: Array.from(this.alerts.values()),
recommendations: this.generateRecommendations(),
metrics: {
snapshots: this.snapshots,
historicalData: {
totalSnapshots: this.snapshots.length,
timeRange: {
start: this.snapshots[0]?.timestamp || 0,
end: latestSnapshot.timestamp
}
}
}
};
}
/**
* Get live dashboard data
*/
getDashboardData(): DashboardData {
const latestSnapshot = this.snapshots[this.snapshots.length - 1];
if (!latestSnapshot) {
throw new Error('No memory snapshots available');
}
// Build component status
const components = Object.entries(latestSnapshot.components).map(([name, data]) => {
const trend = this.trends.get(`${name}-memory`);
return {
name,
memoryUsage: data.memoryUsage,
trend: trend?.trend === 'increasing' ? 'up' as const :
trend?.trend === 'decreasing' ? 'down' as const : 'stable' as const,
status: this.getComponentStatus(name, data),
objectCount: data.objectCount,
growthRate: data.growthRate
};
});
// Build chart data
const recentSnapshots = this.snapshots.slice(-50);
return {
timestamp: Date.now(),
overview: {
totalMemory: latestSnapshot.system.heapTotal,
usedMemory: latestSnapshot.system.heapUsed,
freeMemory: latestSnapshot.system.heapFree,
memoryPressure: latestSnapshot.system.heapUsed / latestSnapshot.system.heapTotal,
alertCount: Array.from(this.alerts.values()).filter(a => !a.acknowledged).length
},
components,
charts: {
memoryUsage: recentSnapshots.map(s => ({
timestamp: s.timestamp,
value: s.system.heapUsed
})),
gcActivity: recentSnapshots.map(s => ({
timestamp: s.timestamp,
duration: s.gcMetrics.lastGCDuration,
type: s.gcMetrics.lastGCType
})),
leakDetection: Array.from(this.alerts.values())
.filter(a => a.type === 'leak')
.map(a => ({
timestamp: a.timestamp,
severity: a.severity,
component: a.component
})),
performance: recentSnapshots.map(s => ({
timestamp: s.timestamp,
metric: 'heap-usage',
value: s.system.heapUsed / s.system.heapTotal
}))
},
recentAlerts: Array.from(this.alerts.values())
.sort((a, b) => b.timestamp - a.timestamp)
.slice(0, 10)
};
}
// Event handlers and notifications
private setupEventHandlers(): void {
// Listen to leak detector events
this.leakDetector.on('memoryLeakDetected', (detection: MemoryLeakDetection) => {
if (this.shouldAlertForLeak(detection)) {
this.createAlert({
type: 'leak',
severity: detection.severity,
component: detection.component,
message: `Memory leak detected: ${detection.leakType}`,
currentValue: detection.currentUsage,
recommendation: detection.recommendation,
autoFixAvailable: detection.autoFixAvailable
});
}
});
// Listen to GC optimizer events
this.gcOptimizer.on('gcMetrics', (metrics: GCMetrics) => {
// Update GC frequency tracking
this.updateGCFrequency(metrics);
});
}
private shouldAlertForLeak(detection: MemoryLeakDetection): boolean {
const severityLevels = { low: 1, medium: 2, high: 3, critical: 4 };
const configLevel = severityLevels[this.config.alertThresholds.leakSeverity];
const detectionLevel = severityLevels[detection.severity];
return detectionLevel >= configLevel;
}
private async handleAlertNotification(alert: MemoryAlert): Promise<void> {
if (!this.config.notifications.enabled) return;
// Console notification
if (this.config.notifications.channels.includes('console')) {
// eslint-disable-next-line no-console
console.warn(`🚨 Memory Alert [${alert.severity.toUpperCase()}]: ${alert.message}`);
// eslint-disable-next-line no-console
console.warn(` Component: ${alert.component}`);
// eslint-disable-next-line no-console
console.warn(` Recommendation: ${alert.recommendation}`);
}
// Escalation handling
if (this.config.notifications.escalationPolicy.enabled) {
this.handleAlertEscalation(alert);
}
}
private handleAlertEscalation(alert: MemoryAlert): void {
const escalationKey = `${alert.component}-${alert.type}`;
const count = this.alertCounts.get(escalationKey) || 0;
this.alertCounts.set(escalationKey, count + 1);
if (count >= this.config.notifications.escalationPolicy.levels) {
this.emit('alertEscalation', {
alert,
escalationLevel: 'maximum',
message: 'Alert has reached maximum escalation level'
});
}
}
private async attemptAutoFix(alert: MemoryAlert): Promise<void> {
try {
switch (alert.type) {
case 'threshold':
if (alert.component === 'system') {
await this.gcOptimizer.forceGarbageCollection('auto-fix-threshold');
}
break;
case 'leak':
await this.leakDetector.forceCleanup();
break;
}
alert.resolvedAt = Date.now();
this.emit('autoFixApplied', alert);
} catch (error) {
this.emit('autoFixFailed', { alert, error });
}
}
// Utility methods
private maintainHistoryWindow(): void {
const cutoff = Date.now() - this.config.historyWindow;
this.snapshots = this.snapshots.filter(s => s.timestamp > cutoff);
if (this.snapshots.length > this.config.maxDataPoints) {
this.snapshots = this.snapshots.slice(-this.config.maxDataPoints);
}
}
private updateDashboard(): void {
if (!this.config.dashboard.enabled) return;
try {
const dashboardData = this.getDashboardData();
this.emit('dashboardUpdate', dashboardData);
} catch (error) {
this.emit('dashboardError', error);
}
}
private updateGCFrequency(_metrics: GCMetrics): void {
// Implementation would track GC frequency over time
}
private getAffectedOperations(pressureLevel: string): string[] {
switch (pressureLevel) {
case 'critical': return ['all-operations', 'gc-pauses', 'allocation-failures'];
case 'high': return ['large-allocations', 'cache-operations', 'evolution-cycles'];
case 'medium': return ['background-processing', 'analytics'];
default: return [];
}
}
private estimateGCImpact(snapshot: MemorySnapshot): number {
const heapUsageRatio = snapshot.system.heapUsed / snapshot.system.heapTotal;
return Math.min(heapUsageRatio * 2, 1); // Estimate pause time impact
}
private getComponentStatus(_name: string, data: any): 'healthy' | 'warning' | 'critical' {
if (data.growthRate > 10 * 1024 * 1024) return 'critical';
if (data.memoryUsage > 50 * 1024 * 1024 || data.poolUtilization > 0.9) return 'warning';
return 'healthy';
}
private calculateLeakRisk(): number {
const recentDetections = this.leakDetector.getStatistics().recentDetections;
const criticalLeaks = recentDetections.filter(d => d.severity === 'critical').length;
const highLeaks = recentDetections.filter(d => d.severity === 'high').length;
return Math.min((criticalLeaks * 0.8 + highLeaks * 0.5) / 10, 1);
}
private calculatePerformanceImpact(): number {
const latestSnapshot = this.snapshots[this.snapshots.length - 1];
if (!latestSnapshot) return 0;
const heapUsageRatio = latestSnapshot.system.heapUsed / latestSnapshot.system.heapTotal;
const alertSeverity = Array.from(this.alerts.values())
.reduce((max, alert) => {
const severityScore = { low: 0.25, medium: 0.5, high: 0.75, critical: 1 };
return Math.max(max, severityScore[alert.severity]);
}, 0);
return Math.min(heapUsageRatio * 0.7 + alertSeverity * 0.3, 1);
}
private generateRecommendations(): {
immediate: string[];
shortTerm: string[];
longTerm: string[];
} {
const immediate: string[] = [];
const shortTerm: string[] = [];
const longTerm: string[] = [];
// Critical alerts require immediate action
const criticalAlerts = Array.from(this.alerts.values()).filter(a => a.severity === 'critical');
immediate.push(...criticalAlerts.map(a => a.recommendation));
// High memory usage
const latestSnapshot = this.snapshots[this.snapshots.length - 1];
if (latestSnapshot) {
const heapUsageRatio = latestSnapshot.system.heapUsed / latestSnapshot.system.heapTotal;
if (heapUsageRatio > 0.8) {
immediate.push('Reduce memory allocation or trigger garbage collection');
}
}
// Trending issues for short-term planning
for (const trend of this.trends.values()) {
if (trend.trend === 'increasing' && trend.confidence > 0.7) {
shortTerm.push(`Address growing memory usage in ${trend.component}`);
}
}
// Hotspots for long-term optimization
for (const hotspot of this.hotspots.values()) {
if (hotspot.severity > 0.7) {
longTerm.push(...hotspot.recommendations);
}
}
return { immediate, shortTerm, longTerm };
}
/**
* Get current monitoring status
*/
getStatus(): {
isMonitoring: boolean;
snapshotCount: number;
alertCount: number;
lastSnapshot?: number;
configuration: MemoryMonitoringConfig;
} {
const lastSnapshotTimestamp = this.snapshots[this.snapshots.length - 1]?.timestamp;
return {
isMonitoring: this.isMonitoring,
snapshotCount: this.snapshots.length,
alertCount: this.alerts.size,
...(lastSnapshotTimestamp !== undefined ? { lastSnapshot: lastSnapshotTimestamp } : {}),
configuration: this.config
};
}
/**
* Acknowledge an alert
*/
acknowledgeAlert(alertId: string): boolean {
const alert = this.alerts.get(alertId);
if (alert) {
alert.acknowledged = true;
this.emit('alertAcknowledged', alert);
return true;
}
return false;
}
/**
* Shutdown monitoring system
*/
shutdown(): void {
this.stopMonitoring();
this.removeAllListeners();
}
}
/**
* Memory Monitoring Integration Utilities
*/
export class MemoryMonitoringIntegration {
private static instance: MemoryMonitoringSystem | null = null;
/**
* Initialize memory monitoring system
*/
static initialize(
config: Partial<MemoryMonitoringConfig>,
performanceTracker: PerformanceTracker,
leakDetector: MemoryLeakDetector,
gcOptimizer: GarbageCollectionOptimizer
): MemoryMonitoringSystem {
if (!this.instance) {
this.instance = new MemoryMonitoringSystem(
config,
performanceTracker,
leakDetector,
gcOptimizer
);
}
return this.instance;
}
/**
* Get current monitoring instance
*/
static getInstance(): MemoryMonitoringSystem | null {
return this.instance;
}
/**
* Shutdown monitoring
*/
static shutdown(): void {
if (this.instance) {
this.instance.shutdown();
this.instance = null;
}
}
}