diff --git a/bookstorm.py b/bookstorm.py index d36e3a1..a72c2cb 100755 --- a/bookstorm.py +++ b/bookstorm.py @@ -813,17 +813,21 @@ class BookReader: pygame.event.clear() # Alternate between fast (gen 0) and full GC - if gcCounter % 600 == 0: + # At 300: gen 0 only (fast) + # At 600: full collection (all generations) + if gcCounter >= 600: gc.collect() # Full collection every 20 seconds + gcCounter = 0 # Reset counter after full GC else: - gc.collect(generation=0) # Fast collection every 10 seconds - + gc.collect(generation=0) # Fast collection at 10 seconds + # Don't reset - let it reach 600 for full GC + # Memory watchdog: warn if exceeding 2GB (50% on Pi 4GB) try: import resource # pylint: disable=no-member memUsage = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024 # MB - + # More aggressive memory warnings and cleanup if memUsage > 1536: # 1.5GB threshold if not memoryWarningShown: @@ -836,17 +840,19 @@ class BookReader: for surfaceType, surface, position in self.cachedSurfaces: del surface self.cachedSurfaces.clear() + # Force mpv player cleanup + if hasattr(self, 'audioPlayer') and self.audioPlayer: + self.audioPlayer._cleanup_temp_files() # Additional garbage collection gc.collect() gc.collect() # Second pass - + if memUsage > 2048 and not memoryWarningShown: memoryWarningShown = True self.speechEngine.speak("Warning: High memory usage detected. Consider restarting BookStorm soon.") except Exception as e: print(f"Memory monitoring error: {e}") pass - gcCounter = 0 # Limit to 30 FPS to avoid CPU spinning clock.tick(30) diff --git a/src/epub_parser.py b/src/epub_parser.py index 3b7a816..0c9335d 100644 --- a/src/epub_parser.py +++ b/src/epub_parser.py @@ -383,53 +383,13 @@ class EpubParser: def cleanup(self): """Clean up temporary files and memory""" try: - # Clear BeautifulSoup objects and other memory references - if hasattr(self, 'soup'): - del self.soup - self.soup = None - if hasattr(self, 'rootfile'): - del self.rootfile - self.rootfile = None - if hasattr(self, 'metadataTag'): - del self.metadataTag - self.metadataTag = None - if hasattr(self, 'manifestTag'): - del self.manifestTag - self.manifestTag = None - if hasattr(self, 'spineTag'): - del self.spineTag - self.spineTag = None - if hasattr(self, 'tocNav'): - del self.tocNav - self.tocNav = None - if hasattr(self, 'navMap'): - del self.navMap - self.navMap = None - - # Clear book content and references - if self.book: - if hasattr(self.book, 'chapters'): - for chapter in self.book.chapters: - if hasattr(chapter, 'paragraphs'): - chapter.paragraphs.clear() - self.book.chapters.clear() - self.book = None - - # Clear dictionaries and lists - if hasattr(self, 'tocMap'): - self.tocMap.clear() - if hasattr(self, 'manifest'): - self.manifest.clear() - if hasattr(self, 'spine'): - self.spine.clear() - - # Force garbage collection + # Force garbage collection to clean up local variables import gc gc.collect() - + except Exception as e: print(f"Warning: Error during memory cleanup: {e}") - + # Clean up temp directory if self.tempDir and Path(self.tempDir).exists(): try: