[OVSDB-471] Excessive memory allocation ("object churn") in OVSDB's Jackson based JSON processing Created: 12/Nov/18  Updated: 16/Nov/18  Resolved: 16/Nov/18

Status: Resolved
Project: ovsdb
Component/s: None
Affects Version/s: Oxygen-SR3
Fix Version/s: Oxygen-SR4, Fluorine-SR2, Neon

Type: Bug Priority: Low
Reporter: Michael Vorburger Assignee: Vishal Thapar
Resolution: Won't Do Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

I'm looking at a Java Flight Recording obtained from (internal) scale lab testing, and see extensive "TLAB Allocations" due to what appears to be something wrong in ovsdb's JSON processing:

char[] java.util.Arrays.copyOfRange(char[], int, int)	2671
void java.lang.String.<init>(char[], int, int)	2671
String java.lang.StringBuilder.toString()	2145
String sun.reflect.generics.parser.SignatureParser.parseIdentifier()	812
SimpleClassTypeSignature sun.reflect.generics.parser.SignatureParser.parsePackageNameAndSimpleClassTypeSignature()	692
ClassTypeSignature sun.reflect.generics.parser.SignatureParser.parseClassTypeSignature()	692
FieldTypeSignature sun.reflect.generics.parser.SignatureParser.parseFieldTypeSignature(boolean)	692
FieldTypeSignature sun.reflect.generics.parser.SignatureParser.parseFieldTypeSignature()	692
TypeArgument sun.reflect.generics.parser.SignatureParser.parseTypeArgument()	370
TypeArgument[] sun.reflect.generics.parser.SignatureParser.parseTypeArguments()	370
SimpleClassTypeSignature sun.reflect.generics.parser.SignatureParser.parsePackageNameAndSimpleClassTypeSignature()	370
ClassTypeSignature sun.reflect.generics.parser.SignatureParser.parseClassTypeSignature()	370
FieldTypeSignature sun.reflect.generics.parser.SignatureParser.parseFieldTypeSignature(boolean)	370
FieldTypeSignature sun.reflect.generics.parser.SignatureParser.parseFieldTypeSignature()	370
TypeSignature sun.reflect.generics.parser.SignatureParser.parseTypeSignature()	370
TypeSignature sun.reflect.generics.parser.SignatureParser.parseTypeSig(String)	309
TypeSignature sun.reflect.generics.repository.FieldRepository.parse(String)	309
Tree sun.reflect.generics.repository.FieldRepository.parse(String)	309
void sun.reflect.generics.repository.AbstractRepository.<init>(String, GenericsFactory)	309
void sun.reflect.generics.repository.FieldRepository.<init>(String, GenericsFactory)	309
FieldRepository sun.reflect.generics.repository.FieldRepository.make(String, GenericsFactory)	309
FieldRepository java.lang.reflect.Field.getGenericInfo()	309
Type java.lang.reflect.Field.getGenericType()	309
JavaType com.fasterxml.jackson.databind.introspect.AnnotatedField.getType()	309
void com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.addBeanProps(DeserializationContext, BeanDescription, BeanDeserializerBuilder)	309
JsonDeserializer com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.buildBeanDeserializer(DeserializationContext, JavaType, BeanDescription)	309
JsonDeserializer com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.createBeanDeserializer(DeserializationContext, JavaType, BeanDescription)	309
JsonDeserializer com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2(DeserializationContext, DeserializerFactory, JavaType, BeanDescription)	309
JsonDeserializer com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializationContext, DeserializerFactory, JavaType)	309
JsonDeserializer com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializationContext, DeserializerFactory, JavaType)	309
JsonDeserializer com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializationContext, DeserializerFactory, JavaType)	309
JsonDeserializer com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializationContext, DeserializerFactory, JavaType)	309
JsonDeserializer com.fasterxml.jackson.databind.DeserializationContext.findNonContextualValueDeserializer(JavaType)	306
void com.fasterxml.jackson.databind.deser.BeanDeserializerBase.resolve(DeserializationContext)	306
JsonDeserializer com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializationContext, DeserializerFactory, JavaType)	306
JsonDeserializer com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializationContext, DeserializerFactory, JavaType)	306
JsonDeserializer com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializationContext, DeserializerFactory, JavaType)	306
JsonDeserializer com.fasterxml.jackson.databind.DeserializationContext.findContextualValueDeserializer(JavaType, BeanProperty)	306
JsonDeserializer com.fasterxml.jackson.databind.deser.std.MapDeserializer.createContextual(DeserializationContext, BeanProperty)	306
JsonDeserializer com.fasterxml.jackson.databind.DeserializationContext.handlePrimaryContextualization(JsonDeserializer, BeanProperty, JavaType)	306
void com.fasterxml.jackson.databind.deser.BeanDeserializerBase.resolve(DeserializationContext)	306
JsonDeserializer com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializationContext, DeserializerFactory, JavaType)	306
JsonDeserializer com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializationContext, DeserializerFactory, JavaType)	306
JsonDeserializer com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializationContext, DeserializerFactory, JavaType)	306
JsonDeserializer com.fasterxml.jackson.databind.DeserializationContext.findContextualValueDeserializer(JavaType, BeanProperty)	306
JsonDeserializer com.fasterxml.jackson.databind.deser.std.MapDeserializer.createContextual(DeserializationContext, BeanProperty)	306
JsonDeserializer com.fasterxml.jackson.databind.DeserializationContext.handlePrimaryContextualization(JsonDeserializer, BeanProperty, JavaType)	306
void com.fasterxml.jackson.databind.deser.BeanDeserializerBase.resolve(DeserializationContext)	306
JsonDeserializer com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializationContext, DeserializerFactory, JavaType)	306
JsonDeserializer com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializationContext, DeserializerFactory, JavaType)	306
JsonDeserializer com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializationContext, DeserializerFactory, JavaType)	306
JsonDeserializer com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(JavaType)	306
JsonDeserializer com.fasterxml.jackson.databind.ObjectMapper._findRootDeserializer(DeserializationContext, JavaType)	306
Object com.fasterxml.jackson.databind.ObjectMapper._convert(Object, JavaType)	306
Object com.fasterxml.jackson.databind.ObjectMapper.convertValue(Object, Class)	306
UpdateNotification org.opendaylight.ovsdb.lib.notation.json.Converter$UpdateNotificationDeser.deserialize(JsonNode)	306
UpdateNotification org.opendaylight.ovsdb.lib.notation.json.Converter$UpdateNotificationConverter.convert(JsonNode)	306
Object org.opendaylight.ovsdb.lib.notation.json.Converter$UpdateNotificationConverter.convert(Object)	306
Object com.fasterxml.jackson.databind.deser.std.StdDelegatingDeserializer.convertValue(Object)	306
Object com.fasterxml.jackson.databind.deser.std.StdDelegatingDeserializer.deserialize(JsonParser, DeserializationContext)	306
Object com.fasterxml.jackson.databind.ObjectMapper._convert(Object, JavaType)	306
Object com.fasterxml.jackson.databind.ObjectMapper.convertValue(Object, Class)	306
void org.opendaylight.ovsdb.lib.jsonrpc.JsonRpcEndpoint.processRequest(Object, JsonNode)	306
void org.opendaylight.ovsdb.lib.jsonrpc.JsonRpcServiceBinderHandler.channelRead(ChannelHandlerContext, Object)	306


 Comments   
Comment by Stephen Kitt [ 13/Nov/18 ]

The JFR results don’t necessarily support the diagnosis given here; in particular

char[] java.util.Arrays.copyOfRange(char[], int, int)	2671
void java.lang.String.<init>(char[], int, int)	2671
String java.lang.StringBuilder.toString()	2145
String sun.reflect.generics.parser.SignatureParser.parseIdentifier()	812

since one call to parseIdentifier() only ever results in one call to StringBuilder.toString().

The JFR stack trace pinpoints majority contributors at each level: the above trace means that there were 2671 calls to copyOfRange(); the most common caller was String’s constructor (in 2671 cases, so in all cases here); the most common caller of the constructor was StringBuilder.toString(), in 2145 cases; the most common caller of StringBuilder.toString() was parseIdentifier(), in 812 cases. That leaves 1859 unexplained calls to copyOfRange().

Comment by Michael Vorburger [ 16/Nov/18 ]

fuhgeddaboudit

Generated at Wed Feb 07 20:36:29 UTC 2024 using Jira 8.20.10#820010-sha1:ace47f9899e9ee25d7157d59aa17ab06aee30d3d.