Java 内存问题

2015-05-19 15:23:27 +08:00
 xuyifei

我在用Java做数据处理的时候发现,用jmap查看Java堆里面内存只有9G,但是free -m 查看系统内存还是有31g,这个问题已经纠结很久了,Java程序在处理高峰的时候内存会涨到23G左右,但是GC之后系统内存却下来。求教各位大神。

jmap :
1022:             1             16  java.lang.String$CaseInsensitiveComparator
Total     133323717     9003962864
[root@localhost sync]# free -m
             total       used       free     shared    buffers     cached
Mem:         32094      31752        342          0        273       1644
-/+ buffers/cache:      29834       2260
Swap:            0          0          0
3785 次点击
所在节点    Java
12 条回复
phx13ye
2015-05-19 15:32:55 +08:00
没看懂你什么意思, 是说系统内存用太多?
贴个arch wiki
Why is Arch using all my RAM?

Essentially, unused RAM is wasted RAM.

Many new users notice how the Linux kernel handles memory differently than they are used to. Since accessing data from RAM is much faster than from a storage drive, the kernel caches recently accessed data in memory. The cached data is only cleared when the system begins to run out of available memory and new data needs to be loaded.

We could distinguish the difference from free command:

$ free -h

total used free shared buff/cache available
Mem: 2.8G 1.1G 283M 224M 1.4G 1.2G
Swap: 3.0G 881M 2.1G

It is important to note the difference between "free" and "available" memory. In the above example, a laptop with 2.8G of total RAM appears to be using most of it, with only 283M as free memory. However, 1.4G of it is "buff/cache". There is still 1.2G available for starting new applications, without swapping. See man free(1) for detail. The result of all this? Performance!
leoYu
2015-05-19 15:47:35 +08:00
1. ps -eo rss,pmem,pcpu,vsize,args | sort -k 1 -r -n | less
发现PID为xxxx的Java进程占用Mem高达9G,出现故障
2. ps -mp xxxx -o THREAD,tid,time | sort -rn
找到了耗占用Mem最高的线程xxxx
3. jstask xxxx拿到dump文件
xuyifei
2015-05-19 16:46:20 +08:00
@phx13ye 谢谢回复,那就是说现在应用内存占了大量的原因是在于buffer和cache中-。-
phx13ye
2015-05-19 16:52:55 +08:00
@xuyifei 是的, linux系统会尽量把内存用上
xuyifei
2015-05-19 18:01:47 +08:00
@leoYu 学习了,2那个能找到耗用mem最高的线程吗,这个只能看到cpu的吧
shiznet
2015-05-19 18:26:24 +08:00
@xuyifei top -H 看看
shiznet
2015-05-19 18:27:20 +08:00
用jmap查看Java堆里面内存只有9G,但是free -m 查看系统内存还是有31g

是已经占用了31G 不是剩余31G
msg7086
2015-05-19 22:51:30 +08:00
@xuyifei 1楼说的和问题完全无关
SoloCompany
2015-05-20 04:01:21 +08:00
没明白你说什么,xmx配置是啥你也没说
jvm的纯 java部分是只会使用堆不会使用系统内存的,要不就是jni占有了大量内存
当然因为存在margin比如gc的时候可能需要额外的内存所以存在偏差很正常但一般不会有3倍这么大的差距
另外内存占用也和其它因素有关比如线程数需要占用堆栈内存
free也看不出什么东西来你好歹至少发个ps的结果啊
xuyifei
2015-05-20 10:52:20 +08:00
@SoloCompany 不好意思,表达不行o(╯□╰)o。这个是
```
-Xms26g -Xmx26g -Xmn12g -XX:PermSize=1024M -Xss2M
```
这是我的部分配置。然后现在问题是我发现使用jmap查看的Java占用的内存和free或者top看到的不一样,
>jvm的纯 java部分是只会使用堆不会使用系统内存的
这句话的意思是Java堆进行垃圾回收之后并不会影响系统内存的大小吗,现在我看到的现象也是如此。
这是` ps -aux|sort -k 1-r |less`部分结果
```
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 7840 20.6 82.5 45954484 27116508 ? Sl May19 236:06 java
```
然后现在的系统内存: `free -m`:
```
free -m
total used free shared buffers cached
Mem: 32094 29282 2812 0 273 1644
-/+ buffers/cache: 27364 4730
Swap: 0 0 0

```
SoloCompany
2015-05-20 11:24:15 +08:00
你这个配置 xms26g 不忍直视啊,如果是这样的话,当然是一启动就全部26g 全分配给 jvm 了,也就是说无论用 ps 还是 free,看到的都应该是26g 被分配走了

至于 jmap 看到的 9g,那应该是堆里面的 used 部分,其余部分是空闲的,但这部分内存已经分配给堆了,系统是不能使用的。至于你的系统繁忙的时候真用到多少内存,只能通过 jmap 或者 jstack 来看,一般来说,大概数字看 jstack 就够了。

另外,这种配置,除非你的系统一直不需要 full gc,否则来一次的话估计要杯具,建议你去看看 jvm 内存优化的文章吧,我暂时也没什么好推荐的
xuyifei
2015-05-20 14:11:44 +08:00
@SoloCompany 好的,感谢

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/192214

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX