json.JSONEncoder.iterencode (and, by extension, json.dump) creates reference cycles on every call where _one_shot is False (the default). This is because it defines three mutually-recursive nested functions, which keep each other alive through their closures.
According to local microbenchmarks adapted from pyperformance, clearing these cycles explicitly results in a ~10% slowdown for json.dump when the GC is disabled, but a ~20% speedup when the GC is enabled (since we're now eagerly doing the work done less efficiently by the GC).
I'll have a patch up soon.