我有一个自己写的内存数据库,在linux上运行,功能正常,就是内存大了些, 用top命令可以看到top - 11:45:54 up 8 days, 21:20,  2 users,  load average: 0.00, 0.00, 0.00
Tasks: 357 total,   1 running, 356 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.4%us,  0.2%sy,  0.0%ni, 99.4%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:  12186888k total,  9619700k used,  2567188k free,    33924k buffers
Swap:  4194296k total,        0k used,  4194296k free,   574212k cached  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  DATA COMMAND                                                           
 3189 root      20   0 12.3g 4.0g 9292 S  5.3 34.6 179:35.23  12g java              用jmap命令可以看到: num     #instances         #bytes  class name
----------------------------------------------
   1:       4477149     2140395920  [B
   2:       9479186      444139176  [C
   3:       8701136      278436352  java.lang.String
   4:        673888      192360376  [I
   5:       4390884      140508288  com.nokia.warlock.imsd.datadef.SessionCacheData
   6:       3935464      125934848  java.util.concurrent.ConcurrentHashMap$HashEntry
   7:       3933343       94400232  com.nokia.warlock.imsd.server.KVStorageBase.BaseDataWrapper

 568:             1             16  sun.reflect.GeneratedMethodAccessor1
 569:             1             16  java.util.regex.Pattern$CharPropertyNames$19
 570:             1             16  sun.misc.Launcher
 571:             1             16  java.util.regex.Pattern$CharPropertyNames$20
 572:             1             16  java.util.regex.Pattern$CharPropertyNames$21
 573:             1             16  sun.misc.Launcher$Factory
 574:             1             16  java.text.MessageFormat$Field
 575:             1             16  sun.net.spi.DefaultProxySelector
 576:             1             16  sun.rmi.server.UnicastRef
Total      38630582     3572785728
请教各位:
 1. 我到底占用的内存是多大呢? 12G 还是 4G?
 2. 像这种情况,可以做些什么优化呢?

解决方案 »

  1.   

    3,572,785,728 bytes 要问12G还是4G,就是4G内存数据库嫌内存用得大我觉得得和数据压缩之类的有关了吧
      

  2.   

    既然是java程序,以jmap为主 3572785728 bytes,换算一下,应该是4G左右
    linux的9619700k used还包括了其他程序占用的内存,所以不能准确地反映内存数据库的内存消耗自己做的内存数据库,首先不管自己做的性能如何,如果数据量大,肯定占内存,因为所有的数据都在内存上
    要知道,像oracle这样的,都不是内存数据库,还是依赖于外部数据文件的说到优化,那就看你自己实现数据库的存储方式和相应的算法了
      

  3.   

    感谢两位。
    如果我的内存是4G的话,为什么会有12G的 VIRT 呢? 是曾经使用的,然后被GC的内存么?
    12G 和 4G差别还是很大的,有没有JVM的参数可以降低VIRT呢? 因为我的机器就只有12G内存,还要跑其他程序,担心内存太大了,到时候要做磁盘交换,性能就大幅下降了。
      

  4.   

    -Xmx
    但你的数据库必须有一些淘汰策略.当内存不够时,把一些内存对象移出内存.或者是存入文件,或者是直接把没用的删除.
      

  5.   

    o: VIRT -- Virtual Image (kb)
        The total amount of virtual memory used by the task. It includes all code, data and shared libraries plus pages that have been swapped out.      VIRT = SWAP + RES.p: SWAP -- Swapped size (kb)
        The swapped out portion of a task's total virtual memory image.q: RES -- Resident size (kb)
        The non-swapped physical memory a task has used.      RES = CODE + DATA.
    What Memory Statistics Does Linux Report?    Virtual memory is the total amount of the address space reserved by the operating system to the process for its code, data and stack. The virtual memory size reported by Linux includes all the code, data and stack space reserved for use by a process, on both physical memory and swap space. This value includes space used by all shared libraries used by the process. The implication of this is that shared libraries count in full towards the size of a given process.    The resident memory size of a process reported by Linux includes only the amount of physical memory the process and the shared libraries it references are using at a given time. Segments moved to swap space are not included. Like with virtual memory size, resident memory size includes the space used by shared libraries.
    Read more: How Much Linux Memory is Used by a Process? | eHow.com http://www.ehow.com/about_5497321_much-linux-memory-used-process.html#ixzz1fM7TFy62
    http://www.ehow.com/about_5497321_much-linux-memory-used-process.html通过以上分析我感觉这个虚拟内存(VIRT)大不能直接意味着什么,毕竟实际使用的就是4g左右,或者还有其它的解释
      

  6.   

    虚拟内存是swap,即交换区,Swap作用:系统物理内存不够用时,需要将物理内存中的一部分空间释放出来,以供当前运行的程序使用。那些被释放的空间可能来自一些很长时间没有什么操作的程序,这些被释放的空间被临时保存到Swap空间中,等到那些程序要运行时,再从Swap中恢复保存的数据到内存中。这样,系统总是在物理内存不够时,才进行Swap交换.你机器物理内存就只有4G。而jvm就已经占了3572785728的空间物理内存不够用就用到了swap。。
    造成这个原因可能:
    1.  内存数据库的数据量比较大,以及数据的存储形式。。
    2.  程序中文件操作频繁。。并发大。。
    3.  程序需要优化
      

  7.   

    vitural 值跟启动时间-Xmx参数有关,不必太在意
    res是实际使用的物理内存