V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
caixiexin
V2EX  ›  Java

为何我的项目运行一段时间后,物理内存使用越来越高?

  •  
  •   caixiexin · 2015-01-03 21:07:05 +08:00 · 6476 次点击
    这是一个创建于 3610 天前的主题,其中的信息可能已经有所发展或是发生改变。
    公司的一个运行在tomcat上的java ee项目,主要功能上是作为接口服务器。服务器上物理内存8G,tomcat启动时jvm初始堆内存以及最大堆内存都设置为1400M,项目运行起来后,物理内存还剩快2G的样子。但是慢慢运行几天后,用top命令看内存使用情况,java进程占用的内存越来越多,最后把物理内存用满了,但是之后就不会在增加(不会去用swap),同时,tomcat性能上感觉没有什么影响,也不会抛出OOM什么的,负载低的时候cpu使用率也不超过10%。

    后来针对这个项目有做过接口的压力测试,接口内部处理逻辑就是接受请求报文后保存到数据库,压测30分钟,机子的物理内存也是越用越多,到最后用满,但是接口的响应速度没有什么影响。整个压测过程,我用visualVM观察jvm的情况,发现堆内存基本上只用了500多M,还没达到最大值(项目启动时给虚拟机分配的初始值和最大值是1400M)。压测结束后,有50多个线程是live状态(tomcat配置的最大线程数300),看了下ThreadDump 貌似都是http请求相关的线程。


    我想请教下,这种情况是否正常?既然分配的堆内存都没用完,那些后来慢慢增长的物理内存用在哪些地方了(难道是线程的栈内存?),为什么随着负载降低,这些物理内存没被释放掉呢。


    这里贴下项目的JVM启动参数和tomcat server.xml设置的一些参数:
    export JAVA_OPTS="-server -Xms1400M -Xmx1400M -Xss512k -XX:+AggressiveOpts -XX:+UseBiasedLocking -XX:PermSize=128M -XX:MaxPermSize=256M -XX:+DisableExplicitGC -XX:MaxTenuringThreshold=31 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:LargePageSizeInBytes=128m -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -Djava.awt.headless=true "

    ----------

    <Connector port="9010" protocol="HTTP/1.1"
    IEncoding="UTF-8" minSpareThreads="25" maxSpareThreads="75"
    disableUploadTimeout="true"
    acceptCount="300" maxThreads="300" maxProcessors="1000" minProcessors="5"
    useURIValidationHack="false"
    compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"
    URIEncoding="UTF-8"
    --------------
    小弟对JVM优化的经验基本为零,各位大大能解惑的话,不胜感激,顺便跪求JVM优化相关的书籍?T_T
    9 条回复    2015-01-04 19:15:09 +08:00
    liuhaotian
        1
    liuhaotian  
       2015-01-03 21:56:46 +08:00 via iPhone   ❤️ 4
    Linux会最高程度利用内存,物理内存高不是问题,要看你的真实内存… 其他的都被缓存了(cache+buffers)
    SoloCompany
        2
    SoloCompany  
       2015-01-04 00:01:48 +08:00   ❤️ 1
    一个线程512k,300个线程就是150m,如果你没有设置线程上限的话,开了3000个线程那就是1.5g
    这些都是使用的物理内存而不是 heap
    ryd994
        3
    ryd994  
       2015-01-04 02:09:36 +08:00 via Android   ❤️ 1
    你是用什么工具看的?free有两行,你要看+-cache那行
    caixiexin
        4
    caixiexin  
    OP
       2015-01-04 07:56:05 +08:00
    @ryd994 用的是top命令,看到Mem那一行大概像这样:Mem: 8388608k total, 8349804k used, 38804k free, 429836k buffers
    caixiexin
        5
    caixiexin  
    OP
       2015-01-04 07:56:51 +08:00
    @liuhaotian 请问下真实内存要怎么呢?
    caixiexin
        6
    caixiexin  
    OP
       2015-01-04 07:58:18 +08:00
    @SoloCompany 有设置最大线程数来着 acceptCount="300" maxThreads="300" maxProcessors="1000" minProcessors="5" 。所以我想就算是线程的栈内存也不该这么大啊。。
    Oishi
        7
    Oishi  
       2015-01-04 08:15:48 +08:00   ❤️ 1
    total used free shared buffers cached
    Mem: 15990 7397 8593 42 490 2092
    -/+ buffers/cache: 4813 11177
    Swap: 4095 0 4095

    第二行才是真是内存使用情况
    caixiexin
        8
    caixiexin  
    OP
       2015-01-04 08:36:50 +08:00
    @Oishi 明白了。。。top命令看到的Mem使用率是包括buffers和cached 两个缓存的,用free看到的-/+ buffers/cache才是真正的内存使用情况。
    我用free看了下内存使用率其实并不高,大部分都是缓存,太感谢了=口=
    thankyourtender
        9
    thankyourtender  
       2015-01-04 19:15:09 +08:00
    别拿缓存不当资源,一台机器就一个tomcat?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2932 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 14:23 · PVG 22:23 · LAX 06:23 · JFK 09:23
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.