基于模型的分布式部署应用工具本身是一个插件,所以在编写的过程中需要对它进行调试,可是开始的时候还一切正常,但是一旦在调试的eclipse平台中打开一个外部文件,就是出现如下的异常:

java.lang.OutOfMemoryError: PermGen space

一看就知道是内存不足了,可是如何解决它却并不顺利。一开始以为是eclipse本身内存分配的不够了,eclipse可以通过在快捷方式中指定参数或者修改eclipse.ini文件来指定初始化参数,调研发现eclipse需要分配2块内存区域来运行,包括堆内存和非堆内存的分配。

堆内存的分配:JVM初始分配的内存由-Xms指定,默认是物理内存的1/64;JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4。默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制。因此服务器一般设置-Xms、-Xmx相等以避免在每次GC后调整堆的大小。

非堆内存分配:JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。程序溢出的是这个部分,也就是永久保存区域的溢出。

所以我在eclipse.ini中新加了3个参数-vmargs -Xms256m -Xmx512m,并且将jee和platform的MaxPerSize设置为了256m,这样可以通过管理控制台发现eclipse.exe进行占用的内存达到了256m,可是仍然无法解决问题。最终发现可以在Run Configurations中设置调试eclipse平台的VM arguments,我在其中加入了

-Xms128m -Xmx256m -XX:PermSize=128m -XX:MaxPermSize=128m

也就是分配了它128m的永久保存区域,这样修改果然有效,调试的eclipse平台无论怎样进行文件操作都不会产生内存溢出的错误了,所以我猜测eclipse在运行一个新的eclipse平台进行调试的时候,是将自身的非堆内存分配了一小部分给新的eclipse平台,并且这块内存及其有限,所以就导致了内存溢出的问题,也有可能是直接就新申请了一小块非堆内存给了新的eclipse平台,所以只要在插件调试的时候设置足够的空间就能避免这种错误了。

PS:如果是双核CPU,从JDK1.5开始,在eclipse.ini添加参数-XX:+UseParallelGC可以让GC更快的运行。