又踩到一个坑——JAVA虚拟机最大内存

飘过的小牛 2013-12-11 09:13:40
最近一直在优化项目,然后想把一个查询频繁的表加载到内存中建立一个HashMap结构,然后tomcat各种listenstart报错,我因为也不太懂JAVA,吭哧吭哧搜了一下午也没搞定。。。

然后问了组里经验丰富的人,说可能是加载的内存过大。然后我一看,我去,这个小破表竟然占了6G。。然后我加了一些筛选条件,大概4G的样子。

然后按网上说的把tomcat的Xmx搞到4500m。。。。然后满怀希望启动,一看日志,我去,超出限制了。百思不得其解啊,又去问人家。人家回来让看看机器是多少位的,说32位的JAVA虚拟机最大内存好像只能开到2G左右。64G可以很大。然后我一看,果然是32位的。。。。

然后我就没有办法了。。。各位,谁能给我解释一下tomcat为啥根据32位、64位限制JAVA虚拟机的大小。机器有12G内存,空闲有10G。。。但是竟然不支持。真是郁闷的不行,然后用servlet访问一个接口,就报NullPointerException,我估计是因为数据没加载到内存,这个接口一查发现数据是空的,然后就扔过来一个异常。(这是我猜的,希望你能根据经验给我判断一下。。)

谢谢各位了。。谁能给点建议更好,明天跟mentor商量一下,换个64的机器来搞~~
...全文
2399 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
树成 2013-12-12
  • 打赏
  • 举报
回复
我很奇怪,公司为什么要你这个完全不懂系统设计的人去优化项目。看你对内存和架构的理解,似乎无法完成这个工作... 一个6GB数据的表,是不可以这样放入内存的- -。而且很多时候,也不需要这种优化,通常只要建立索引和一些逻辑处理上的优化基本上就能适用所有的业务系统。如果并发量实在大,流量巨大,实在是数据太频繁适用,那就要硬件的支持和良好的设计了,就算数据使用很频繁,也不可能6GB数据都很频繁- -,只要统计出6GB中哪些频繁然后缓存就可以了,就像java的内存回收机制。 如果是数据分析系统的话,我只能告诉你,以你目前的硬件配置还无法完成任务,当然还需要一个针对性的设计以及大量的代码优化,着同样不是以你现在的水平能够完成的,需要一个很资深的在大数据处理上有经验的人来处理。
sliwey 2013-12-12
  • 打赏
  • 举报
回复
64位的貌似最大也就8G的内存 楼主的优化方案 应该得改下
rumlee 2013-12-12
  • 打赏
  • 举报
回复
从你的这个问题看,即使给了你64位系统也不一定能解决你的问题。 这么大的数据量全部加载到内存的HashMap中,这种设计肯定是有问题的。 HashMap虽然通过hash值进行了快速定位的优化,但是归根到底HashMap的定位方式还是遍历,小数据量定位很快,但是大数据量性能将会非常的差,性能远没有数据库的索引采用Btree之类的结构搜索来的快。所以可能你是想优化系统,结果把系统给优化到坑里了。
teemai 2013-12-12
  • 打赏
  • 举报
回复
首先你把表里的东西都加载到内存当中,这本身就不合理。就不能分页查询? 其次32位操作系统,支持内存到4G,而系统已经占用一部分内存,所以你的程序可用内存更少。而且如果是32位系统,你插入8G/16G内存条,可识别内存也不会超过4G。
  • 打赏
  • 举报
回复
一个表站6个G我觉得楼主还是放弃把它放内存的想法吧!
聪头 2013-12-12
  • 打赏
  • 举报
回复
有第三方缓存插件,可以使用。如memcache
浪漫小和 2013-12-12
  • 打赏
  • 举报
回复
你为什么要把那么多的数据加载到内存呢?
oh_Maxy 2013-12-12
  • 打赏
  • 举报
回复
引用 1 楼 rumlee 的回复:
你太扯了,你32的操作系统,怎么支持12G内存的啊。 32位操作系统最大也就只能支持4G内存啊。这是根据操作系统内存寻址有关的。比如表示一个内存地址的指针用一个32位的空间来存放,所以肯定只能支持这么大内存啊。学过操作系统的应该理解啊。
顶一个~ 前两天也看了相关内容,大概意思是说,32位的操作系统,它的寻址最大就是2的32次方的内存空间了,内存分配多了就超出范围,超出部分还是寻不到的。因此,jdk或者tomcat在校验初始化内存大小的时候,会考校这个系统位数的(这块是推论的)。
  • 打赏
  • 举报
回复
又学习了!!!操作系统白学了!
飘过的小牛 2013-12-12
  • 打赏
  • 举报
回复
嗯,跟大家说下。问题解决了,是另外一个地方没考虑到导致的空指针。 给大家一个建议就是看帖子要看仔细点。。 我明明说的是: 真是郁闷的不行,然后用servlet访问一个接口,就报NullPointerException,我估计是因为数据没加载到内存,这个接口一查发现数据是空的,然后就扔过来一个异常。(这是我猜的,希望你能根据经验给我判断一下。。) 所以,如果有经验的应该马上知道不是内存的问题,而是什么地方抛出了异常。所以,在网上跟一个大牛描述了一下,他立即说跟内存无关,是你空指针问题。然后我定位以后发现果然是有个地方忘记判断了。 这才是我想要的答案。总之,也学到了很多东西,谢谢大家!结贴
搬运工木木 2013-12-12
  • 打赏
  • 举报
回复
32位的系统,开了PAE的确是有超过4G内存可用量显示的,不过你tomcat用的JDK应该是32位的,另外,也不清楚这种开了PAE的32位系统是否支持64位JDK,估计是不支持的。 64位系统,你装32位JDK,我印象中最多也只能用4G,而且如果是windows系统的话,很可能4G都用不到,应该是tomcat直接就起不来了 楼主你的需求,可能需要的是一个搜索引擎来提高性能
coolbamboo2008 2013-12-12
  • 打赏
  • 举报
回复
这么多数据一次读入内存,也不现实的吧
JPF1024 2013-12-12
  • 打赏
  • 举报
回复
今晚就遇到了一个,装PS的时候,看到提示安装64位的会更好用一些。 机器决定的吧,估计在JVM内部设置的32位和64位所占用的最大内存不一样。
「已注销」 2013-12-12
  • 打赏
  • 举报
回复
还是无法理解将这么大的数据放入内存。如果要优化的话,可以首先考虑对于当前数据库查询方式的优化,或者从头处理一下应对逻辑。 我机器也是32位的,4G内存,不能都用,现实的hi3.17G可用。
zhouylf 2013-12-12
  • 打赏
  • 举报
回复
java虚拟机的内存大小跟系统有关,一般64位的大于32位,linux系统大于window系统的
sliwey 2013-12-12
  • 打赏
  • 举报
回复
引用 14 楼 niushuai666 的回复:
[quote=引用 10 楼 u011559804 的回复:] 64位的貌似最大也就8G的内存 楼主的优化方案 应该得改下
64的话,2的64次方。不是简单的叠加。[/quote] 是我犯2了。。。64位的理论值是很大的 但是硬件有限制啊。。。
飘过的小牛 2013-12-12
  • 打赏
  • 举报
回复
引用 10 楼 u011559804 的回复:
64位的貌似最大也就8G的内存 楼主的优化方案 应该得改下
64的话,2的64次方。不是简单的叠加。
飘过的小牛 2013-12-12
  • 打赏
  • 举报
回复
引用 9 楼 rumlee 的回复:
从你的这个问题看,即使给了你64位系统也不一定能解决你的问题。 这么大的数据量全部加载到内存的HashMap中,这种设计肯定是有问题的。 HashMap虽然通过hash值进行了快速定位的优化,但是归根到底HashMap的定位方式还是遍历,小数据量定位很快,但是大数据量性能将会非常的差,性能远没有数据库的索引采用Btree之类的结构搜索来的快。所以可能你是想优化系统,结果把系统给优化到坑里了。
这个有道理。谢谢
飘过的小牛 2013-12-12
  • 打赏
  • 举报
回复
引用 1 楼 rumlee 的回复:
你太扯了,你32的操作系统,怎么支持12G内存的啊。 32位操作系统最大也就只能支持4G内存啊。这是根据操作系统内存寻址有关的。比如表示一个内存地址的指针用一个32位的空间来存放,所以肯定只能支持这么大内存啊。学过操作系统的应该理解啊。
我当时也纳闷的不行啊。。。看机器明明是12G内存。但是确实是32位的。 我纠正一下,32位不是只能支持4G的。如果开启PAE的话,最大支持64G。只是一个进程最多只能寻址4G的内存。所以,tomcat作为一个进程,无法使用大于4G的空间。可能是这个原因吧。。
qiuqiupeng 2013-12-11
  • 打赏
  • 举报
回复
2的32次方就是4G了,建议找个商业咨询机构咨询方案后再处理吧
加载更多回复(1)

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧