问题起因是这篇文章结尾的问题。
排查了小半个上午,结论是因为xstream默认构造器时会new一个CompositeClassLoader导致内存泄漏,GC root不断增加,但触发一次FullGC后,PermGen得到清理,所以时间又会降下来。
解决办法是传固定的ClassLoader而不是每次都new一个。
内网的ATATech的51137文章也详细描述了原因。
题外话,这个问题最初在StackOverflow上提问,得到了一片老外们关于GC的质疑(甚至没有一个人尝试去跑过代码),倒也不枉我对SO小白社区的印象。