当我向云服务器(PasS,128Mb)部署战争时遇到问题,然后在我的应用程序中有两个计时器。Timer1
将每小时执行一次任务以记录我的内存(以及#2中描述的Map)。
每次创建“房间”对象时,都会将此房间放入地图中,因此当我启动“房间”以从地图中删除该对象时,我就有一个Timer2
来创建任务。
我碰巧知道我不应该使用计时器。
但是问题是我检查了Timer1记录的日志,我的freeMemory
每小时下降一次,总内存是相同的。
我已经读过What are Runtime.getRuntime().totalMemory() and freeMemory()?,所以我知道总内存和freeMemory意味着什么。并且根据日志,我的已用内存正在增加!
PS:我不使用任何新的Runnable或Thread来处理任何长时间运行的逻辑。
日志就像:
2014-07-22 04:39:27 [ Timer-10:44100005 ] - [ INFO ]
maxMemory()=128
totalMemory() = 75
freeMemory()= 44
2014-07-22 04:39:27 [ Timer-10:44100005 ] - [ INFO ] Now there are Existing Room of : 0
2014-07-22 05:39:27 [ Timer-10:47700005 ] - [ INFO ]
maxMemory()=128
totalMemory() = 75
freeMemory()= 41
2014-07-22 05:39:27 [ Timer-10:47700005 ] - [ INFO ] Now there are Existing Room of : 0
2014-07-22 06:39:27 [ Timer-10:51300006 ] - [ INFO ]
maxMemory()=128
totalMemory() = 75
freeMemory()= 39
每当此sevlet收到请求时,我都会记录日志,因此我确定不会处理任何请求,但是为什么可用内存减少了。
1. Timer1的工作方式如下:
@Override
public void init() throws ServletException {
super.init();
LogUtil.info("CoreServlet inits");
memoryTimer=new Timer(true);
//check the memory every 1 hour,first time will be delayed to 15 mins later
memoryTimer.schedule(new checkMemoryTask(),TimeConstant.FIFTHTEEN_MINUTES_MILISECONDS,TimeConstant.ONE_HOUR_MILISECONDS);
commandService = CommandService.getInstance();
}
2.这就是Timer2的工作方式。
public Room newRoom() {
Integer randomNumObject;
LogUtil.debug("Trying to new a room with the random number");
//generate a random number util the number is not a existing room number
do {
randomNumObject=generateRandom(4);//4 digits room number
} while (roomMap.containsKey(randomNumObject));//roomNum is existing, continue to find
Room newRoom=new Room(randomNumObject);//use this number to create a new room
roomMap.put(randomNumObject, newRoom);
//abandon the room after 15 MINTES
roomClearTimer.schedule(new abandonRoomTask(randomNumObject.intValue()), TimeConstant.FIFTHTEEN_MINUTES_MILISECONDS);
LogUtil.info(newRoom+" is scheduled to be abandoned 15 MINUTES later");
return newRoom;
}
最佳答案
这里根本没有真正的问题。
正如freeMemory()
的Javadoc所述:
返回Java虚拟机中的可用内存量。调用gc方法可能会增加freeMemory返回的值。
实际上,在Java程序中通常发生的情况是,当您分配新对象时,可用内存量减少了相同的数量。当可用内存量达到阈值(由JVM确定)时,GC将在后台运行,并回收大量垃圾。这将导致可用内存再次备份。
只有在垃圾回收后立即的可用内存量持续下降的情况下,您才有问题(例如内存泄漏)。
在您的特定情况下,freeMemory()
呈下降趋势的原因是正在分配对象。 (Timer2
似乎是新对象的一种可能来源,但也可能是Web容器代码。)
如果这些对象最终没有得到垃圾回收,这只是一个问题。