Class: Lich::Util::MemoryReleaser::Manager

Inherits:
Object
  • Object
show all
Defined in:
documented/util/memoryreleaser.rb

Overview

Core manager class that handles memory release operations and background thread management

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeManager

Initialize a new Manager instance

Loads settings from persistent storage if available, otherwise uses defaults.



158
159
160
161
# File 'documented/util/memoryreleaser.rb', line 158

def initialize
  load_settings
  @enabled = true
end

Instance Attribute Details

#enabledBoolean

Returns whether the memory releaser is enabled.

Returns:

  • (Boolean)

    whether the memory releaser is enabled



142
143
144
# File 'documented/util/memoryreleaser.rb', line 142

def enabled
  @enabled
end

#intervalInteger

Returns interval in seconds between automatic memory releases.

Returns:

  • (Integer)

    interval in seconds between automatic memory releases



145
146
147
# File 'documented/util/memoryreleaser.rb', line 145

def interval
  @interval
end

#settingsHash (readonly)

Returns current settings.

Returns:

  • (Hash)

    current settings



151
152
153
# File 'documented/util/memoryreleaser.rb', line 151

def settings
  @settings
end

#verboseBoolean

Returns whether to output verbose logging.

Returns:

  • (Boolean)

    whether to output verbose logging



148
149
150
# File 'documented/util/memoryreleaser.rb', line 148

def verbose
  @verbose
end

Instance Method Details

#auto_disable!void

This method returns an undefined value.

Disable auto-start and stop the memory releaser

This method disables the auto_start setting, saves it, and immediately stops the memory releaser if it's running.



225
226
227
228
229
# File 'documented/util/memoryreleaser.rb', line 225

def auto_disable!
  @settings[:auto_start] = false
  save_settings
  stop if running?
end

#auto_start!Thread?

Enable auto-start and start the memory releaser

This method enables the auto_start setting, saves it, and immediately starts the memory releaser with the current interval and verbose settings.

Returns:

  • (Thread, nil)

    the background thread, or nil if failed to start



210
211
212
213
214
# File 'documented/util/memoryreleaser.rb', line 210

def auto_start!
  @settings[:auto_start] = true
  save_settings
  start
end

#benchmarkvoid

This method returns an undefined value.

Run a memory release benchmark showing before/after statistics

This method displays detailed memory statistics before and after a memory release operation, including the changes in heap slots, pages, malloc usage, and process RSS.

Examples:

MemoryReleaser.benchmark
# => ============================================================
# => Memory Usage Before Release:
# => ============================================================
# =>   Ruby Heap Live Slots:           123456
# =>   ...


412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
# File 'documented/util/memoryreleaser.rb', line 412

def benchmark
  respond "=" * 60
  respond "Memory Usage Before Release:"
  respond "=" * 60
  before = print_memory_stats

  respond "\nReleasing memory..."
  release

  respond "\n" + "=" * 60
  respond "Memory Usage After Release:"
  respond "=" * 60
  after = print_memory_stats

  respond "\n" + "=" * 60
  respond "Change:"
  respond "=" * 60
  print_memory_diff(before, after)
end

#interval!(seconds) ⇒ Integer

Update the interval setting

Examples:

MemoryReleaser.interval!(600) # Set to 10 minutes

Parameters:

  • seconds (Integer)

    the new interval in seconds

Returns:

  • (Integer)

    the new interval value



238
239
240
241
242
243
244
245
246
247
248
249
250
251
# File 'documented/util/memoryreleaser.rb', line 238

def interval!(seconds)
  seconds = [seconds, 60].max # Minimum 60 seconds
  @settings[:interval] = seconds
  @interval = seconds
  save_settings

  # If currently running, restart with new interval
  if running?
    log "Restarting with new interval: #{seconds}s"
    start
  end

  seconds
end

#load_settingsHash

Load settings from persistent storage

Settings are stored per-character using InstanceSettings. If no stored settings exist, defaults are used.

Returns:

  • (Hash)

    the loaded settings



169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'documented/util/memoryreleaser.rb', line 169

def load_settings
  # Load from InstanceSettings with per-character scope
  stored_settings = Lich::Common::InstanceSettings['memoryreleaser'] || {}
  @settings = DEFAULT_SETTINGS.merge(stored_settings)

  # Apply loaded settings to instance variables
  @interval = @settings[:interval]
  @verbose = @settings[:verbose]

  @settings
rescue => e
  # If there's an error loading settings, use defaults
  respond "[MemoryReleaser] Error loading settings: #{e.message}, using defaults"
  @settings = DEFAULT_SETTINGS.dup
  @interval = @settings[:interval]
  @verbose = @settings[:verbose]
  @settings
end

#releasevoid

This method returns an undefined value.

Perform a complete memory release cycle

Prunes stale entries from the GameObj shared identity index using the current interval as the TTL - any index entry not seen within the last @interval seconds (and not held in an active registry) is evicted before the GC and OS-level release steps run. This ensures the index stays lean and the subsequent GC pass has the most to reclaim.

Runs Ruby's garbage collector with full mark and immediate sweep, attempts to compact the heap if available, and then releases memory back to the operating system using platform-specific methods.



280
281
282
283
284
285
286
287
288
# File 'documented/util/memoryreleaser.rb', line 280

def release
  before = print_memory_stats if @verbose
  Lich::Common::GameObj.prune_index!(ttl: @interval, verbose: @verbose)
  run_gc
  release_to_os
  after = print_memory_stats if @verbose
  print_memory_diff(before, after) if @verbose
  log "Memory release completed"
end

#running?Boolean

Check if the background thread is currently running

Returns:

  • (Boolean)

    true if the background thread is alive, false otherwise



365
366
367
368
# File 'documented/util/memoryreleaser.rb', line 365

def running?
  worker = MemoryReleaser.worker_thread
  worker&.alive? || false
end

#save_settingsHash

Save current settings to persistent storage

Settings are stored per-character using InstanceSettings character scope.

Returns:

  • (Hash)

    the saved settings



193
194
195
196
197
198
199
# File 'documented/util/memoryreleaser.rb', line 193

def save_settings
  # Save current settings back to InstanceSettings with per-character scope
  Lich::Common::InstanceSettings['memoryreleaser'] = @settings
rescue => e
  respond "[MemoryReleaser] Error saving settings: #{e.message}"
  @settings
end

#start(interval: nil, verbose: nil) ⇒ Thread?

Start the background memory release thread

Stops any existing thread before starting a new one. The thread will sleep for the specified interval between memory release cycles.

This method uses a persistent launcher thread pattern to ensure threads survive script termination in environments like Lich where script-spawned threads are killed when the script exits. The launcher thread is created at module load time and persists at the main engine level.

Examples:

Start with saved settings

MemoryReleaser.start

Start with custom interval and verbose output

MemoryReleaser.start(interval: 600, verbose: true)

Parameters:

  • interval (Integer, nil) (defaults to: nil)

    time in seconds between memory releases (default: uses saved setting)

  • verbose (Boolean, nil) (defaults to: nil)

    whether to enable verbose logging (default: uses saved setting)

Returns:

  • (Thread, nil)

    the background thread, or nil if failed to start



309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
# File 'documented/util/memoryreleaser.rb', line 309

def start(interval: nil, verbose: nil)
  stop if running?

  # Use provided values or fall back to settings
  @interval = interval || @settings[:interval]
  @verbose = verbose.nil? ? @settings[:verbose] : verbose
  @enabled = true

  # Update settings with current values
  @settings[:interval] = @interval
  @settings[:verbose] = @verbose
  save_settings

  # Send command to persistent launcher thread
  MemoryReleaser.command_queue << {
    action: :start_worker,
    interval: @interval,
    verbose: @verbose,
    manager: self
  }

  # Wait for worker to start
  timeout = 0
  until running?
    sleep 0.1
    timeout += 1
    if timeout > 50
      respond "[MemoryReleaser] ERROR: Worker thread failed to start"
      return nil
    end
  end

  MemoryReleaser.worker_thread
end

#statusHash

Get the current status of the memory releaser

Examples:

status = MemoryReleaser.status
puts "Running: #{status[:running]}"
puts "Auto-start: #{status[:auto_start]}"
puts "Interval: #{status[:interval]} seconds"
puts "Platform: #{status[:platform]}"

Parameters:

  • return (Hash)

    a customizable set of options

Returns:

  • (Hash)

    status information



386
387
388
389
390
391
392
393
394
395
# File 'documented/util/memoryreleaser.rb', line 386

def status
  {
    running: running?,
    enabled: @enabled,
    auto_start: @settings[:auto_start],
    interval: @interval,
    verbose: @verbose,
    platform: RbConfig::CONFIG['host_os']
  }
end

#stopvoid

This method returns an undefined value.

Stop the background memory release thread

Sends a stop command to the launcher thread which will kill the worker thread. This is a graceful shutdown that respects the launcher thread architecture.



351
352
353
354
355
356
357
358
359
360
# File 'documented/util/memoryreleaser.rb', line 351

def stop
  @enabled = false

  MemoryReleaser.command_queue << {
    action: :stop_worker
  }

  sleep 0.2
  log "Memory releaser stopped"
end

#verbose!(enabled) ⇒ Boolean

Update the verbose setting

Examples:

MemoryReleaser.verbose!(true)

Parameters:

  • enabled (Boolean)

    whether to enable verbose logging

Returns:

  • (Boolean)

    the new verbose value



260
261
262
263
264
265
# File 'documented/util/memoryreleaser.rb', line 260

def verbose!(enabled)
  @settings[:verbose] = enabled
  @verbose = enabled
  save_settings
  enabled
end