java - freeMemory()在没有任何请求的情况下在tomcat中每隔一小时下降一次

标签 java tomcat memory-management memory-leaks

我在部署war到云服务器时遇到问题(PasS,128Mb),然后我的应用程序中有两个定时器。

  1. Timer1 将每隔一小时执行一次任务来记录我的内存(以及 #2 中描述的 map )。
  2. 每次我创建一个 Room 对象时,我都会将这个房间放入一个 Map 中,因此我有一个 Timer2 来在我启动一个 Room 时创建一个任务以从 map 中删除该对象。

我碰巧知道我不应该使用计时器。

但问题是我检查了 Timer1 记录的日志,我的 freeMemory 每小时都在下降,总内存是相同的。

我已阅读 What are Runtime.getRuntime().totalMemory() and freeMemory()? ,所以我知道 total memory 和 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 所述:

Returns the amount of free memory in the Java Virtual Machine. Calling the gc method may result in increasing the value returned by freeMemory.

事实上,在 Java 程序中通常发生的情况是,当您分配新对象时,可用内存量会减少相同的量。当可用内存量达到阈值(由 JVM 确定)时,GC 在后台运行,并回收一堆垃圾。这会导致可用内存再次恢复。

只有在垃圾回收后立即的可用内存量持续下降时,您才会遇到问题(例如内存泄漏)。


在您的特定情况下,freeMemory() 呈下降趋势的原因是正在分配对象。 (Timer2 似乎是新对象的一种可能来源,但它也可能是 Web 容器代码。)

只有当这些对象最终没有被垃圾回收时,这才是一个问题。

关于java - freeMemory()在没有任何请求的情况下在tomcat中每隔一小时下降一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24878270/

相关文章:

java - 创建 servlet 完成时发生错误?

web-services - 生成网络服务时出错

objective-c - @"Strings"在内存中是如何分配的?

java - Spring Boot中没有存储库的多个mongo

java - NewRelic 支持 AWS Lambda 上的 Java 应用程序吗?

java - 如何知道spring boot中嵌入了哪个tomcat版本

iOS:lldb EXC_BAD_ACCESS 自定义单元格

ruby-on-rails - Chrome 扩展 session 管理 : How to authorize user account on rails 3 back-end via plugin

java - Hazelcast 集群映射配置

java - 使用C++的CDC绘制图像的代码可以在Java中使用吗?