mirror of
https://github.com/internetarchive/heritrix3.git
synced 2026-08-06 06:41:12 +00:00
Avoid PermGen OOMEs using serailization constructor magic
* AutoKryo
cache constructors created to deserialize classes that otherwise lack the right no-arg constructors
This commit is contained in:
@@ -3,6 +3,8 @@ package org.archive.bdb;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import sun.reflect.ReflectionFactory;
|
||||
|
||||
@@ -14,6 +16,10 @@ import com.esotericsoftware.kryo.SerializationException;
|
||||
* other classes to register together, and use the same (Sun-JVM-only) trick
|
||||
* for deserializing classes without no-arg constructors.
|
||||
*
|
||||
* newInstance technique and constructor caching inspired by the
|
||||
* KryoReflectionFactorySupport class of Martin Grotzke's kryo-serializers
|
||||
* project. <https://github.com/magro/kryo-serializers>
|
||||
*
|
||||
* TODO: more comments!
|
||||
*
|
||||
* @contributor gojomo
|
||||
@@ -44,6 +50,9 @@ public class AutoKryo extends Kryo {
|
||||
}
|
||||
}
|
||||
|
||||
protected static final ReflectionFactory REFLECTION_FACTORY = ReflectionFactory.getReflectionFactory();
|
||||
protected static final Object[] INITARGS = new Object[0];
|
||||
protected static final Map<Class<?>, Constructor<?>> CONSTRUCTOR_CACHE = new ConcurrentHashMap<Class<?>, Constructor<?>>();
|
||||
|
||||
@Override
|
||||
public <T> T newInstance(Class<T> type) {
|
||||
@@ -54,12 +63,14 @@ public class AutoKryo extends Kryo {
|
||||
ex = se;
|
||||
}
|
||||
try {
|
||||
final Constructor<?> constructor =
|
||||
ReflectionFactory.getReflectionFactory().newConstructorForSerialization(
|
||||
type,
|
||||
Object.class.getDeclaredConstructor( new Class[0] ) );
|
||||
constructor.setAccessible( true );
|
||||
Object inst = constructor.newInstance( new Object[0] );
|
||||
Constructor<?> constructor = CONSTRUCTOR_CACHE.get(type);
|
||||
if(constructor == null) {
|
||||
constructor = REFLECTION_FACTORY.newConstructorForSerialization(
|
||||
type, Object.class.getDeclaredConstructor( new Class[0] ) );
|
||||
constructor.setAccessible( true );
|
||||
CONSTRUCTOR_CACHE.put(type, constructor);
|
||||
}
|
||||
Object inst = constructor.newInstance( INITARGS );
|
||||
return (T) inst;
|
||||
} catch (SecurityException e) {
|
||||
e.printStackTrace();
|
||||
|
||||
Reference in New Issue
Block a user