| """ |
| Memory management utilities for efficient-context. |
| """ |
|
|
| import logging |
| import gc |
| import os |
| import psutil |
| from typing import Optional, Dict, Any |
| from contextlib import contextmanager |
|
|
| |
| logging.basicConfig(level=logging.INFO) |
| logger = logging.getLogger(__name__) |
|
|
| class MemoryManager: |
| """ |
| Manages memory usage for efficient context handling. |
| |
| This class provides utilities to monitor and optimize memory usage |
| when working with large language models and context on CPU. |
| """ |
| |
| def __init__( |
| self, |
| target_usage_percent: float = 80.0, |
| aggressive_cleanup: bool = False, |
| memory_monitor_interval: Optional[float] = None, |
| ): |
| """ |
| Initialize the MemoryManager. |
| |
| Args: |
| target_usage_percent: Target memory usage as percentage of available memory |
| aggressive_cleanup: Whether to perform aggressive garbage collection |
| memory_monitor_interval: Interval for memory monitoring in seconds (None to disable) |
| """ |
| self.target_usage_percent = target_usage_percent |
| self.aggressive_cleanup = aggressive_cleanup |
| self.memory_monitor_interval = memory_monitor_interval |
| self.monitor_active = False |
| |
| logger.info( |
| "MemoryManager initialized with target usage: %.1f%%", |
| target_usage_percent |
| ) |
| |
| def get_memory_usage(self) -> Dict[str, Any]: |
| """ |
| Get current memory usage statistics. |
| |
| Returns: |
| stats: Dictionary of memory usage statistics |
| """ |
| |
| process = psutil.Process(os.getpid()) |
| process_memory = process.memory_info() |
| |
| |
| system_memory = psutil.virtual_memory() |
| |
| |
| process_percent = (process_memory.rss / system_memory.total) * 100 |
| system_percent = system_memory.percent |
| |
| return { |
| "process_rss_bytes": process_memory.rss, |
| "process_vms_bytes": process_memory.vms, |
| "process_percent": process_percent, |
| "system_available_bytes": system_memory.available, |
| "system_total_bytes": system_memory.total, |
| "system_used_percent": system_percent, |
| } |
| |
| def log_memory_usage(self) -> None: |
| """Log memory usage statistics.""" |
| stats = self.get_memory_usage() |
| |
| logger.info( |
| "Memory usage: Process: %.1f%% (%.1f MB), System: %.1f%% (%.1f GB available)", |
| stats["process_percent"], |
| stats["process_rss_bytes"] / (1024 * 1024), |
| stats["system_used_percent"], |
| stats["system_available_bytes"] / (1024 * 1024 * 1024) |
| ) |
| |
| def cleanup_memory(self) -> None: |
| """Perform memory cleanup.""" |
| |
| collected = gc.collect() |
| |
| if self.aggressive_cleanup: |
| |
| collected += gc.collect() |
| |
| logger.debug("Memory cleanup: Collected %d objects", collected) |
| |
| def _check_memory_threshold(self) -> bool: |
| """ |
| Check if memory usage exceeds the target threshold. |
| |
| Returns: |
| exceeded: Whether the threshold is exceeded |
| """ |
| stats = self.get_memory_usage() |
| return stats["system_used_percent"] > self.target_usage_percent |
| |
| @contextmanager |
| def optimize_memory(self): |
| """ |
| Context manager for optimizing memory during operations. |
| |
| Example: |
| ``` |
| with memory_manager.optimize_memory(): |
| # Run memory-intensive operations |
| ``` |
| """ |
| |
| if logger.isEnabledFor(logging.DEBUG): |
| self.log_memory_usage() |
| |
| try: |
| |
| yield |
| finally: |
| |
| if self._check_memory_threshold(): |
| logger.info("Memory threshold exceeded, performing cleanup") |
| self.cleanup_memory() |
| |
| |
| if logger.isEnabledFor(logging.DEBUG): |
| self.log_memory_usage() |
|
|