MyEclipse JVM内存配置及性能调优




 

在使用

MyEclipse

的过程中经常出现内存不足的提示:

 

MyEclipse 

has 

detected 

that 

less 

than 

5% 

of 

the 

31MB 

of 

Eden 

Space 

(Heap 

memory) 

space 

remains. It is strongly recommended that you exit and restart MyEclipse with new virtual machine 

memory paramters to increase this memory. Failure to do so can result in data loss. 

Recommended memory arguments: 

-vmargs 

-Xmx512m 

-XX:MaxPermSize=256m 

-XX:ReservedCodeCacheSize=64m 

提示中说的很明白:

“MyEclipse 

has 

detected 

that 

less 

than 

5% 

of 

the 

64MB 

of 

Perm 

Gen 

(Non-heap memory) s

pace remains.”

意思是说当前只有小于

5%

的非堆内存是空闲的。

 

解决办法:

 

打开

Eclipse

目录,找到

Eclipse.ini

配置文件。

 

打开可以看到如下配置信息

 

-vmargs 

 

-Xmx256m 

-XX:MaxPermSize=64m 

修改如下:

 

-vmargs 

-Xms512m //

配置堆内存的最小值

 

-Xmx512m //

配置堆内存的最大值

 

-XX:PermSize=128M //

配置非堆内存的最小值

 

-XX:MaxPermSize=128M //

配置非堆内存的最大值

 

 

 

(Heap)

和非堆

(Non-heap)

内存

 

按照官方的说法:

“Java 

虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内

存均从此处分配。堆是在

 

Java 

虚拟机启动时创建的。

”“

JVM

中堆之外的内存称为非堆

内存

(Non-

heap 

memory)”

。可以看出

JVM

主要管理两种类型的内存:堆和非堆。简单来说

堆就是

Java

代码可及的内存,是留给开发人员使用的;非堆就是

JVM

留给自己用的,所以

方法区、

JVM

内部处理或优化所需的内存

(

JIT

编译后的代码缓存

)

、每个类结构

(

如运行

时常数池、字段和方法数据

)

以及方法和构造方法的代码都在非堆内存中。

 

1)

 

堆内存的分配

 

JVM

初始分配的内存由

-Xms

指定,默认是物理内存的

1/64

JVM

最大分配的内存由

-Xmx

指定,

默认是物理内存的

1/4

默认空余堆内存小于

40%

时,

JVM

就会增大堆直到

-Xmx

的最大限制;空余堆内存大于

70%

时,

JVM

会减少堆直到

-Xms

的最小限制。因此服务器一

般设置

-Xms

-Xmx

相等以避免在每次

GC 

后调整堆的大小。

 

2)

 

非堆内存的分配

 

JVM

使

-XX:PermSize

1/64

XX:MaxPermSize

设置最大非堆内存的大小,默认是物理内存的

1/4

 

 

JVM

性能调优

 

jvm

将内存分为

new

(存放

jvm

刚分配的

java

对象)

tenured

(存放没被垃圾回收掉的

java

对象)

perm

(存放

class

method

元信息

--

代码)

 

三种,其中

New

Tenured

属于堆

内存,堆内存会从

JVM

启动参数(

-Xmx:3G

)指定的内存中分配;

Perm

不属于堆内存,由

jvm

直接分配,但可以通过

-XX:PermSize -XX:MaxPermSize

 

等参数调整其大小。

 

New

又分为几个部分:

 

1)

 

Eden

Eden

用来存放

JVM

刚分配的对象

 

2)

 

Survivor1 

3)

 

Survivro2

:两个

Survivor

空间一样大,当

Eden

中的对象经过垃圾回收没有被回收

掉时,会在两个

Survivor

之间来回

Copy

,当满足某个条件,比如

Copy

次数,就

会被

Copy

Tenured

显然,

Survivor

只是增加了对象在年轻代中的逗留时间,

加了被垃圾回收的可能性。

 

垃圾回收算法可以分为三类,都基于标记

-

清除(复制)算法:

 

1)

 

Serial

算法(单线程)

 

2)

 

并行算法

 

3)

 

并发算法

 

JVM

会根据机器的硬件配置对每个内存代选择适合的回收算法,比如,如果机器多于

1

个核,会对年轻代选择并行算法,关于选择细节请参考

JVM

调优文档。

 

稍微解释下的是,

并行算法是用多线程进行垃圾回收,

回收期间会暂停程序的执行,

并发算法,

也是多线程回收,但期间不停止应用执行。所以,

并发算法适用于交互性高的一

些程序。经过观察,

并发算法会减少年轻代的大小,其实就是使用了一个大的年老代,

这反

过来跟并行算法相比吞吐量相对较低。

 

垃圾回收动作执行条件:

 

1)

 

当年轻代内存满时,会引发一次普通

GC

,该

GC

仅回收年轻代。需要强调的时,

年轻代满是指

Eden

代满,

Survivor

满不会引发

GC 

2)

 

当年老代满时会引发

Full GC

Full GC

将会同时回收年轻代、年老代

 

3)

 

当永久代满时也会引发

Full GC

,会导致

Class

Method

元信息的卸载

 

4)

 

抛出

OutOfMemoryException

的条件(不是内存被耗空的时候才抛出)

 

5)

 

JVM98%

的时间都花费在内存回收

 

6)

 

每次回收的内存小于

2% 

满足这两个条件将触发

OutOfMemoryException

,这将会留给系统一个微小的间隙以做

一些

Down

之前的操作,比如手动打印

Heap Dump

你可能感兴趣的:(myeclipse,java)