前段时间使用beego框架开发了好多web接口,苦于beego框架对http接口的单元测试支持的不是很好,在迭代空隙修直接使用httprouter作为路由。然后写一个rest接口入参为新增接口uri、实现接口的.so路径和实现rest接口的函数。发现确实可以实现动态热插拔,线上可以更新接口实现逻辑。但是发现了一个问题,就是每次编译出来的.so有点太大了,动不动就是几十MB的大小,而且发现随着接口的注册,程序中动态库占用内存会越来越大。而且这部分占用的内存空间是pprof包无法监控到的。而且还有一个问题,就是同一个方法更新的话不能用同一个.so。

笔者亲测服务top信息如下:

top - 15:52:13 up 157 days, 5:32, 0 users, load average: 0.16, 0.20, 0.18
Tasks: 3 total, 1 running, 2 sleeping, 0 stopped, 0 zombie
%Cpu(s): 1.8 us, 1.6 sy, 0.0 ni, 96.6 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 32947512 total, 300380 free, 18178132 used, 14469000 buff/cache
KiB Swap: 0 total, 0 free, 0 used. 14353928 avail Mem

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 1058868 76240 45852 S 0.0 0.2 0:00.74 measurecom+
41 root 20 0 18504 3436 3016 S 0.0 0.0 0:00.01 bash
51 root 20 0 36592 3064 2632 R 0.0 0.0 0:00.00 top

通过pprof查看,golang只申请的内存微乎其微。可是程序语句占用了差不多1G的内存。
查看/proc/pid/maps,信息如下:
7f30f8d3a000-7f30f984c000 r-xp 00000000 fd:10 1246364961 /data/services/measurecommon/dep/test5.so
7f30f984c000-7f30f9a4c000 —p 00b12000 fd:10 1246364961 /data/services/measurecommon/dep/test5.so
7f30f9a4c000-7f30f9ff9000 r–p 00b12000 fd:10 1246364961 /data/services/measurecommon/dep/test5.so
7f30f9ff9000-7f30fa037000 rw-p 010bf000 fd:10 1246364961 /data/services/measurecommon/dep/test5.so
7f30fa037000-7f30fa05b000 rw-p 00000000 00:00 0
7f30fa05b000-7f30fab6d000 r-xp 00000000 fd:10 1167699471 /data/services/measurecommon/dep/test4.so
7f30fab6d000-7f30fad6d000 —p 00b12000 fd:10 1167699471 /data/services/measurecommon/dep/test4.so
7f30fad6d000-7f30fb31a000 r–p 00b12000 fd:10 1167699471 /data/services/measurecommon/dep/test4.so
7f30fb31a000-7f30fb358000 rw-p 010bf000 fd:10 1167699471 /data/services/measurecommon/dep/test4.so
7f30fb358000-7f30fb37c000 rw-p 00000000 00:00 0
7f30fb37c000-7f30fbe8e000 r-xp 00000000 fd:10 1246364945 /data/services/measurecommon/dep/test3.so
7f30fbe8e000-7f30fc08e000 —p 00b12000 fd:10 1246364945 /data/services/measurecommon/dep/test3.so
7f30fc08e000-7f30fc63b000 r–p 00b12000 fd:10 1246364945 /data/services/measurecommon/dep/test3.so
7f30fc63b000-7f30fc679000 rw-p 010bf000 fd:10 1246364945 /data/services/measurecommon/dep/test3.so
7f30fc679000-7f30fc69d000 rw-p 00000000 00:00 0
7f30fc69d000-7f30fd1af000 r-xp 00000000 fd:10 1246364944 /data/services/measurecommon/dep/test2.so
7f30fd1af000-7f30fd3af000 —p 00b12000 fd:10 1246364944 /data/services/measurecommon/dep/test2.so
7f30fd3af000-7f30fd95c000 r–p 00b12000 fd:10 1246364944 /data/services/measurecommon/dep/test2.so
7f30fd95c000-7f30fd99a000 rw-p 010bf000 fd:10 1246364944 /data/services/measurecommon/dep/test2.so
7f30fd99a000-7f30fd9be000 rw-p 00000000 00:00 0
7f30fd9be000-7f30fe4d0000 r-xp 00000000 fd:10 1146231468 /data/services/measurecommon/dep/test1.so
7f30fe4d0000-7f30fe6d0000 —p 00b12000 fd:10 1146231468 /data/services/measurecommon/dep/test1.so
7f30fe6d0000-7f30fec7d000 r–p 00b12000 fd:10 1146231468 /data/services/measurecommon/dep/test1.so
7f30fec7d000-7f30fecbb000 rw-p 010bf000 fd:10 1146231468 /data/services/measurecommon/dep/test1.so
7f30fecbb000-7f30fecdf000 rw-p 00000000 00:00 0
7f30fecdf000-7f30ff7f1000 r-xp 00000000 fd:10 1166678298 /data/services/measurecommon/dep/test.so
7f30ff7f1000-7f30ff9f1000 —p 00b12000 fd:10 1166678298 /data/services/measurecommon/dep/test.so
7f30ff9f1000-7f30fff9e000 r–p 00b12000 fd:10 1166678298 /data/services/measurecommon/dep/test.so
7f30fff9e000-7f30fffdc000 rw-p 010bf000 fd:10 1166678298 /data/services/measurecommon/dep/test.so
可以看出通过plugin链接进golang程序会大量增加占用的内存。所以在使用plugin热更新的时候,当发现程序占用内存陡增的时候,可以考虑下是这个原因。