-
-
Notifications
You must be signed in to change notification settings - Fork 942
Closed
Milestone
Description
Environment Information
- JRuby version
jruby 9.4.8.0 (3.1.4) 2024-07-02 4d41e55a67 OpenJDK 64-Bit Server VM 11.0.23+9 on 11.0.23+9 [arm64-darwin])
Actual Behavior
To allow garbage collection as soon as possible, we call the following methods to release memory once a JRuby plugin is shut down, but the base JVM process keeps running.
def release_jruby_runtime_memory
logger.info "Release JRuby runtime memory..."
runtime = JRuby.runtime
runtime.release_class_loader
# Clear loaded features to allow sooner garbage collection of it.
# JRuby runtime will not be garbage collected right away due to thread local soft references to JRuby ThreadContext objects.
clear_loaded_features(runtime)
# Clear boundMethods
runtime.getBoundMethods.clear
clear_concurrent_hash_map_fields(runtime)
release_memory_of_large_objects(runtime)
rescue => e
logger.error "release_jruby_runtime_memory failed with #{e.class.name}: #{e.message}"
end
def clear_loaded_features(runtime)
load_service = runtime.getLoadService
load_service.getLoadedFeatures.clear
f = load_service.java_class.declared_field("librarySearcher")
f.accessible = true
library_searcher = f.value(load_service)
loaded_features_index_method = library_searcher.java_class.declared_method('getLoadedFeaturesIndex')
loaded_features_index_method.accessible = true
loaded_features_index = loaded_features_index_method.invoke(library_searcher)
loaded_features_index.clear
f = library_searcher.java_class.declared_field("loadedFeaturesIndex")
f.accessible = true
f.set_value(library_searcher, loaded_features_index.class.new)
rescue => e
logger.error "clear_loaded_features failed with #{e.class.name}: #{e.message}"
end
def clear_concurrent_hash_map_fields(runtime)
%w(allModules constantNameInvalidators).each do |field_name|
f = runtime.java_class.declared_field(field_name)
f.accessible = true
(value = f.value(runtime)).clear
f.set_value(runtime, value.class.new)
end
rescue => e
logger.error "clear_concurrent_hash_map_fields #{field_name} failed with #{e.class.name}: #{e.message}"
end
def release_memory_of_large_objects(runtime)
{
"symbolTable" => runtime.getSymbolTable.class.new(JRuby.runtime),
"javaSupport" => runtime.loadJavaSupport
}.each do |field_name, new_value|
f = JRuby.runtime.java_class.declared_field(field_name)
f.accessible = true
f.set_value(runtime, new_value)
end
rescue => e
logger.error "release_memory_of_large_objects #{field_name} failed with #{e.class.name}: #{e.message}"
end
Expected Behavior
The above teardown actions could be added to the org.jruby.Ruby.teardown logic to fully free up the memory that JRuby used.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels