前言
1. OutOfMemoryError: Java heap space
这个应该是是最常见的内存溢出报错。
例子:
沙县小吃大厅=heap space;坐下吃饭=正常的业务请求;吃饭完离开=业务请求结束;打扫餐桌=GC内存回收
需要明确的:
- 大厅容量有限,因此能放下的桌子是有限的
- 不能让食客坐有上一个食客吃完之后还未清理的桌子
- 食客用餐期间不能清理食客的桌子
- 打扫桌子是服务员定时的或在没有桌子可用的时候进行打扫
- 没桌子可用是打扫桌子需要等所有能打扫的桌子打扫完之后才能继续提供服务
- 不可能让食客吃完之后顺便打扫桌子
好,以上明确之后,我们来用这个例子说明Java heap space溢出的问题
讲解:
正常情况下食客来吃沙县小吃 –> 老板招待食客坐下 –> 食客点餐,吃饭
–> 食客离开 –> 老板定时收拾桌子。
上面的情况是正常的情况,一切看着都是在有序的进行。有一天,可能是由于这个沙县小吃做的比较好吃,突然火了,成网红店了,食客突然增多了。店面还是那个店面,桌子数量还是那么多,来一个食客坐下吃饭,再来一个食客坐下吃饭。食客吃完,走了,打扫桌子,接待下一个顾客。可是一下进来吃饭的人太多,桌子被占满了,又有食客来了,完了,没地方坐了,这时候没办法,暂停接待客人,让食客等着,开始打扫桌子,后面陆续有食客来,还得让食客等着,排的队越来越长,等待时间也越来越长,长到超过食客忍耐的极限,就相当于tomcat访问不了了。
其实会发现,问题很简单,就是能接待的食客数量低于要来吃饭的食客数量。
可能有人会说,店面扩大点,多摆点桌子就好了,这其实就相当于增大heap space。是,这确实是一个解决方法,但那样的话有三个问题:
- 成本会增加很多
- 可用土地面积就那么大了,店面不允许扩大了
- 增加桌子数量之后,还是不够,等桌子占满的时候,开始暂停接待客人,进行全面打扫,由于桌子面积不变,桌子数量增多,全部打扫完的时间也就变长,因此暂停接待的时间就增加了,体验也不好。
这时候有第二种方案,减小桌子大小,比如之前只有8人桌,来一个人也得坐8人桌,所以可以接待的客人就少了。那我优化下,去掉一些8人桌,换成4人桌和2人桌,是不是可以接待的客人就多了?最后发现不能再减小桌子大小了,怎么办,开分店!有钱了,任性了,开分店。
这就是方案三了,开了分店之后,相应的能接待的人就多了。