当前位置:首页 > 知识

用友t系列内存溢出

用友T系列的用友内存溢出,十有八九不是列内用友的锅,是存溢出你自己乱点出来的。

上个月我去一家制造业客户那儿处理报表卡死的用友问题。财务主管急得团团转,列内说U8系统一到月底结账就死,存溢出鼠标转圈转到天荒地老。用友我打开任务管理器一看,列内javaw.exe(用友T+的存溢出后台服务)内存占用2.3G,物理内存8G的用友服务器,光它一个进程就吃掉了近三成。列内再往下翻,存溢出还有个叫“报表引擎”的用友进程,内存1.1G——这玩意儿本该在报表关闭后自动释放的列内。

说白了,存溢出内存溢出就是程序申请内存时发现没地方放了,然后抛异常,再然后整个服务崩掉。用友T系列(T3、T6、T+)全是Java写的后端,Java有个毛病:内存回收(GC)不主动,除非堆满了才动手。你操作越快,产生的垃圾对象越多,堆越满,GC越频繁,系统越卡,最后直接OutOfMemoryError。

但真正让我无语的是客户的操作习惯。那财务主管每天上班第一件事,打开T+,然后最小化,一整天不关。中间查了上百次库存,每次查完直接关查询窗口,从来不用“清空条件”按钮。你知道这些查询条件对象在Java堆里存多久吗?直到GC触发才清。如果查询条件里带了个大范围的日期段——比如查全年流水——那这个对象可能占几十兆内存,堆里堆上几十个,不溢出才怪。

还有个更隐蔽的坑:用友T系列的报表打印组件。客户打印凭证时喜欢点“预览”,预览完不关窗口,直接再点“打印”。这个预览窗口每次会加载完整的打印模板和字体资源,关掉时只释放了界面,资源句柄还挂在服务端。连续预览个二三十次,内存曲线就跟心电图似的往上窜。我见过最夸张的一次,一个用户单日预览了86次,服务器内存直接爆了,整个公司所有人都登不进去。

解决这事儿,别急着加内存条。先改设置:用友T+安装目录下有个`bin\sysConfig.bat`,打开后能找到JVM启动参数,默认`-Xmx512m`——512兆,这年头随便开几个窗口就满了。改成`-Xmx2048m`,甚至`-Xmx4096m`,前提是你服务器物理内存够。但光改这个治标不治本,你堆给大了,垃圾堆积的时间反而更长,GC一次停顿好几秒,报表打开像幻灯片。

真正的关键在数据库连接池。用友T系列默认连接池大小是20,但每个连接背后都绑定了一堆会话状态。你们公司要是超过20个人同时操作,后面的请求就在排队等待连接释放,排队的请求对象全堆在内存里。把连接池上限提到50,同时把`wait_timeout`从默认的28800秒改到600秒,让空闲连接早点断掉。改完这个,我客户那边内存占用直接降了40%。

最后说个土办法,但特别管用:每天中午让所有用户退出一次系统,重启一下用友服务。别嫌麻烦,Java程序跑久了,堆里全是碎片,重启是最彻底的清理。我给那家客户写了个计划任务,每天12点自动重启T+服务,运行两周后再没出过内存溢出。他们财务主管还问我是不是换了新服务器,我说没换,就是把你们乱点的毛病治了。

分享到: