JVM -Xmx -Xms 配置,与误区
-Xmx1024m 越大越好?
作者在一家小公司,负责程序的开发和维护,每当(x64环境)线上的服务节点出现内存溢出的情况我总是采取
提高 -Xmx1024m 的措施来增加堆内存(Heap)大小的问题,
在我下意识里我一直以为,程序访问量大了去提高Heap就ok
实则不然。
Heap越大限制并发量
进程模型
如图所示:
x86的机器上的 进程 最多可以使用 2048mb的内存,
假设 /** VM Args -Xmx 1024 **/ 那么
该Java进程剩下的内存由, 方法区,程序计数器,虚拟机栈,本地方法栈 共同使用。
虚拟机栈使用的空间 = 2048- Xmx(最大堆容量)-MaxPermSize (最大方法区容量) - 本地方法栈
我们知道,一个线程对应一个虚拟机栈,
所以总结:那么Heap 越大可以供,程序申请的内存空间越少,就是说虚拟机栈越少(线程数量越少)
堆内存存储了对象,我们称为GC堆,我们增加-Xmx 只是增加了GC堆的大小正真执行程序的内存空间反而小了
虚拟机栈图解
如图:右边绿色是虚拟机栈
(每个线程里面都是顺序执行的,里面的所有的,程序的执行都在栈帧里,若一段代码调用一个方法就会产生一个新的栈帧压到栈里去),
因此:一个方法我们可以理解为一个栈帧,
用个更好理解的图:
用IDEA 调试的时候,Debugger 就显示了栈帧信息, FILO(First in last out )
如何提高并发
(只有理论指导 ?)
更具OOM Dump,来调优
- 对于高并发,创建对象不多的项目,可以降低Xmx的配置, 结合Xms 设定堆范围 -Xms256m -Xmx512
- 对于低并发,创建对象多的项目,(数据处理型的) 可以适当提高,Xmx
- (因为对象和数组是存放到Heap内的,栈帧中其实只存了对象地址,所以不存在爆的情况)