目录
一、问题背景
JAVA中涉及到流的操作需要注意字符编码集的问题,特别是与Properties结合使用时,需要注意字符编码集,否则可能会触发配置文件的指数性膨胀。
如果使用字节流FileInputStream读取properties文件,再使用字符流OutputStreamWriter写入properties文件,同时指定编码集为"utf-8"格式,而配置文件中properties刚好有中文value,就会出现一个很可怕的问题:随着配置文件内容的不断更新,配置文件的大小会呈指数型膨胀。
由于字节流是不需要指定编码集的,所以这种使用的情况对于程序员来说还是有蛮常见的,特别是像这种properties这种工具式的代码,到处都是ctrl c + ctrl v。
二、问题分析
举个例子:
在GBK编码下,1个汉字占2个字节;在UTF-8编码下,一个汉字占1~4个字节,正常是3个字节。
现在我的配置文件中存在一个中文配置(xxxx为四个汉字,读取时为8个字节):
"route.default.serviceName=xxxx"
首次对配置文件进行load和store时,它的结果可能会变成:
"route.default.serviceName=æ¨è¯·æ±ç"
再次对配置文件进行load和store时,它的结果可能会变成:
"route.default.serviceName=æ¨请æ±ÂçÂÂ"
假设配置文件的更新次数为x,那么value的大小大约会变化成:8*((3/2)**x)
什么概念呢?
也就是说,随着动态配置文件的自动更新,大约更新了20~30次,四个汉字将会占用1~2G的空间。
配置文件这么大,程序还能读取吗?还能正常提供服务吗?
别问我怎么知道的,我的配置文件膨胀到1.6G,直接OOM。