Skip to content

Commit

Permalink
Fix #1995 (with bound of 4000 cached deserializers)
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Apr 11, 2018
1 parent 3fd96e8 commit 141d09b
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 17 deletions.
1 change: 1 addition & 0 deletions release-notes/VERSION
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,5 @@ Versions: 3.x (for earlier see VERSION-2.x)
#1973: Remove support for "default [Map] key serializer" configuration from
`SerializerProvider`
#1994: Limit size of `SerializerCache`, auto-flush on exceeding
#1995: Limit size of `DeserializerCache`, auto-flush on exceeding
- Remove `MappingJsonFactory`
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.fasterxml.jackson.databind.deser;

import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;

import com.fasterxml.jackson.annotation.JsonFormat;

Expand All @@ -12,10 +11,10 @@
import com.fasterxml.jackson.databind.type.*;
import com.fasterxml.jackson.databind.util.ClassUtil;
import com.fasterxml.jackson.databind.util.Converter;
import com.fasterxml.jackson.databind.util.SimpleLookupCache;

/**
* Class that defines caching layer between callers (like
* {@link ObjectMapper},
* Class that defines caching layer between callers (like {@link ObjectMapper},
* {@link com.fasterxml.jackson.databind.DeserializationContext})
* and classes that construct deserializers
* ({@link com.fasterxml.jackson.databind.deser.DeserializerFactory}).
Expand All @@ -25,6 +24,11 @@ public final class DeserializerCache
{
private static final long serialVersionUID = 3L;

/**
* By default allow caching of up to 4000 deserializers.
*/
public final static int DEFAULT_MAX_CACHED = 4000;

/*
/**********************************************************************
/* Caching
Expand All @@ -34,42 +38,45 @@ public final class DeserializerCache
/**
* We will also cache some dynamically constructed deserializers;
* specifically, ones that are expensive to construct.
* This currently means bean and Enum deserializers; starting with
* 2.5, container deserializers will also be cached.
*<p>
* Given that we don't expect much concurrency for additions
* (should very quickly converge to zero after startup), let's
* define a relatively low concurrency setting.
* This currently (3.0) means POJO, Enum and Container (collection,
* map) deserializers.
*/
private final transient ConcurrentHashMap<JavaType, JsonDeserializer<Object>> _cachedDeserializers
= new ConcurrentHashMap<JavaType, JsonDeserializer<Object>>(64, 0.75f, 4);
private final SimpleLookupCache<JavaType, JsonDeserializer<Object>> _cachedDeserializers;

/**
* During deserializer construction process we may need to keep track of partially
* completed deserializers, to resolve cyclic dependencies. This is the
* map used for storing deserializers before they are fully complete.
*/
private final transient HashMap<JavaType, JsonDeserializer<Object>> _incompleteDeserializers
= new HashMap<JavaType, JsonDeserializer<Object>>(8);
= new HashMap<>(8);

/*
/**********************************************************************
/* Life-cycle
/**********************************************************************
*/

public DeserializerCache() { }
public DeserializerCache() { this(DEFAULT_MAX_CACHED); }

public DeserializerCache(int maxSize) {
int initial = Math.min(64, maxSize>>2);
_cachedDeserializers = new SimpleLookupCache<>(initial, maxSize);
}

private DeserializerCache(DeserializerCache src) {
_cachedDeserializers = src._cachedDeserializers;
}

/*
/**********************************************************************
/* JDK serialization handling
/**********************************************************************
*/

// 11-Apr-2018, tatu: instead of clearing or such on write, keep everything transient,
// recreate as empty. No point trying to revive cached instances
// Need to re-create just to initialize `transient` fields
protected Object readResolve() {
return new DeserializerCache();
return new DeserializerCache(this);
}

/*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ public SerializerCache() {
* @since 3.0
*/
public SerializerCache(int maxCached) {
_sharedMap = new SimpleLookupCache<TypeKey, JsonSerializer<Object>>(maxCached>>2, maxCached);
int initial = Math.min(64, maxCached>>2);
_sharedMap = new SimpleLookupCache<TypeKey, JsonSerializer<Object>>(initial, maxCached);
_readOnlyMap = new AtomicReference<ReadOnlyClassToSerializerMap>();
}

Expand Down

0 comments on commit 141d09b

Please sign in to comment.