Skip to content

json.Marshal allocates a lot of unnecessary memory #324

@apelisse

Description

@apelisse

This is a follow-up of #315/#319. Now that Unmarshaling has been fixed, we need to worry about the next big thing, Marshaling.

As we can see from the pprof heap profile (alloc_space) below, json.Marshal is allocating a lot of memory, certainly because it serializes in buffers that are quickly discarded as these buffers are "concatenated" (e.g. https://github.com/kubernetes/kube-openapi/blob/master/pkg/validation/spec/header.go#L44-L63, https://github.com/kubernetes/kube-openapi/blob/master/pkg/validation/spec/schema.go#L435-L466)
profile002

There's clearly no great way to do that with json.Marshal v1, since when you have multiple embedded types (which we have everywhere in the spec), only one of the custom marshaller is called. That's also true for json.Marshal v2, I don't see how it could be different anyways.

I've been looking at go-json-experiment, but I can't find a good way to "embed" multiple values, all the methods require that you serialize exactly one json "value", but in most cases, we want to serialize a list of fields for each of these embedded sub-structures. I think we could give each of these types a "MarshalKeysAndValues", and construct the object itself, but then we will have to rewrite a lot of logic to extract the keys and values.

Anyways, I'm stuck. Suggestions welcome @dsnet @alexzielenski @liggitt

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions