fastjson/src/main/java/com/alibaba/fastjson/JSON.java
Line 1284 in 14a95cc
| | privatestaticchar[] allocateChars(intlength) { |
private final static ThreadLocal<char[]> charsLocal = new ThreadLocal<char[]>();
private static char[] allocateChars(int length) {
char[] chars = charsLocal.get();
if (chars == null) {
if (length <= 1024 * 64) {
chars = new char[1024 * 64];
charsLocal.set(chars);
} else {
chars = new char[length];
}
} else if (chars.length < length) {
chars = new char[length];
}
return chars;
}
直接使用65536个字符是不是太浪费了?大部分场景下都是小对象,但是65536直接内存常驻,利用率非常低,内存水位直接被ThreadLocal拉高,无法GC掉。大对象用不到,小对象还浪费……
5条答案
按热度按时间nle07wnf1#
啊这~ 这是大问题啊,简单搜了下,
allocateChars
在JSON.parse
中被用到,并且完全没有释放的地方。只要100个常驻线程有用过这东西,直接就是6G内存消耗?@wenshaopinkon5k2#
啊这~ 这是大问题啊,简单搜了下,
allocateChars
在JSON.parse
中被用到,并且完全没有释放的地方。只要100个常驻线程有用过这东西,直接就是6G内存消耗?@wenshao6M,要是6G早就全员原地炸了😂。
mqkwyuun3#
最近几天,线上服务器元空间一直在增长, 于是把预发环境机器的内存dump出来看一下, 无意间发现很多Dubbo线程和MQ线程
把持
了很多内存空间, 上百KB, 不应该呀, 看了业务代码, 看了架构组提供的Jar包是否存在默认拦截器之类的, 但是都没有找到导致问题的根源. 下班后花了2天还是没查到问题, 第3天, 还是回到dump文件, 继续分析它找了一个MQ线程,看一下它内部属性
继续查看内部的ThreadLocalMap
在它的112槽存储了一个128.05KB字节数组, 里面的信息就是业务打印的日志内容.
继续查看哪些类使用了这个java.lang.ThreadLocal @ 0x701392b28
发现了class com.alibaba.fastjson.JSON @ 0x700f14d78这个对象的charsLocal使用了上面的ThreadLocal
查看源码后, 大吃一惊, 这个ThreadLocal只负责set, 造成很多线程都
把持
很多无用的信息, 浪费了很多内存空间.du7egjpx4#
看上面的回复说, 这个问题已经修复了 . 而经过测试最新的1.2.79版本 以及查看master代码和1.2.79版本代码, fastjson并没有主动
帮助
使用者清除ThreadLocal. 官方是希望使用者自己去手动清除ThreadLocal? @wenshao附录
个人理解, 在内存空间和执行效率两者的选择上, fastjson依然选择效率优先, 宁愿牺牲一些内存空间, 也不会放弃效率, 因此也不会调整原有代码逻辑, 是吗?
iecba09b5#
看上面的回复说, 这个问题已经修复了 . 而经过测试最新的1.2.79版本 以及查看master代码和1.2.79版本代码, fastjson并没有主动
帮助
使用者清除ThreadLocal. 官方是希望使用者自己去手动清除ThreadLocal? @wenshao附录 个人理解, 在内存空间和执行效率两者的选择上, fastjson依然选择效率优先, 宁愿牺牲一些内存空间, 也不会放弃效率, 因此也不会调整原有代码逻辑, 是吗?
Maybe the author has not considered this issue~