eclipse GC机制

来源:互联网 发布:淘宝发布销售属性错误 编辑:程序博客网 时间:2024/05/29 14:30
Xms
JVM初始分配的堆内存由Xms指定,默认的是物理内存的1/64;JVM最大分配的堆内存由-Xmx指定。
Xmx
JVM最大允许分配的堆内存,按需分配
-XX:PermSize
JVM初始分配的非堆内存
-XX:MaxPermSize
JVM最大允许分配的非内存,按需分配


JVM内存管理的机制
堆(Heap)和非堆(Non-Heap)内存
按照官方的说法:“Java虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处
分配。堆石在Java虚拟机启动时创建的。”“在JVM中堆之外的内存成为非堆内存(Non-heap memory)。”
可以看出JVM主要管理两种类型的内存:堆和非堆。简单来说堆就是Java代码可及的内存,是留给开发人
员使用的;非堆是留给自己用的,所以方法区、JVM内部处理或优化所需的内存(如JIT编译后的代码缓存)、
每个类结构(如运行时常数池、字段和方法数据)以及方法和构造都在非堆内存中。

堆内存分配
JVM初始分配的对内存由-Xms指定,默认是物理内存的1/64;JVM最大分配的对内存由-Xmx指定,默认是
物理地址的1/4。默认空余堆内存小雨40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%
JVM会减少堆直到-Xms的最小限制。因此服务器一般设置-Xms、-Xmx相等以避免在每次GC后调整堆的大小。
说明:如果-Xmx不指定或者指定偏小,应用可能会导致java.lang.OutOfMemory错误,此错误来自JVM,
不是Throwable的,不能用try...catch捕捉。

非堆内存分配
JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;由XX:MaxPermSize设置最大非堆内存
的大小,默认是物理内存的1/4。(还有一说:MaxPermSize缺省值和-server -client选项相关,-server
选项下默认MaxPermSize为64M,-client选项下默认MaxPermSize为32M。)
上面错误信息中的PermGen space的全称是Permanent Genneration space,是指内存的永久保存区域。
还没有弄明白PermGen spce是属于非堆内存,还是就是非堆内存,但至少是属于了。
XX:MaxPermSize设置过小会导致java.lang.OutOfMemoryError:PermGen space就是内存溢出。
说说为什么会内存溢出:
(1)这一部分内存用于保存Class和Meta的信息,Class在被Load的时候被放入PermGen space区域,它和存
放Instance的Heap区域不同。
(2)GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,所以如果你的App会Load很
多Class的话,就很可能出现PermGgen space错误。
这种错误常见在web服务器对JSP进行pre compile的时候。

2)JVM内存限制(最大值)
首先JVM内存限制于实际的最大物理内存,假如物理内存无限大的话,JVM内存的最大值跟操作系统有很大关
系。简单的说就32位处理器虽然可控内存空间有4GB,但是具体的操作系统会给一个限制,这个限制一般是
2GB-3GB(一般来说Windows系统下为1.5-2G,Linux系统下为2G-3G),而64bit以上的处理器就不会有限制了。

注意:如果你的内存是1024MB,但实际上系统中用到的并不可能是1024MB,因为有一部分被硬件占用了。

为何将上面的参数写入到eclipse.ini文件Eclipse,没有执行对应的设置?
那为什么同样的参数在快捷方式或者命令行中有效而在eclipse.ini文件中是无效的呢?
这是因为我们没有遵守eclipse.ini文件的设置规则:
参数形如“项 值”这种形式,中间有空格的需要换行书写,如果值中有空格的需要用双引号包括起来。比如
我们使用-vm C:/Java/jre1.6.0/bin/javaw.exe参数设置虚拟机,在eclipse.ini文件中要写成这样:
C:/Java/jre1.6.0/bin/javaw.exe
-vmargs
-Xms128M
-Xmx512M
-XX:PermSize=64M
-XX:MaxPermSize=128M

建议:将相同的第三方jar文件移置到tomcat/shared/lib目录下,这样可以减少jar文档重复占用内存。

-Xmn(新世代大小)


JVM里的GC(Garbage Collection)的算法有很多种,如标记清除收集器,压缩收集器,分代收集器等等。
现在比较常用的是分代收集(generation collection,也是SUN VM使用的,J2SE1.2之后引入),即将
内存分为几个区域,将不同生命周期的对象放在不同区域里:young generation,tenured generation和
permanet generation。绝大部分的object被分配在young generation(生命周期短),并且大部分的
object在这里die。当young generation满了之后,将引发minor collection(YGC)。在minor
collection 后存活的object会被移动到tenured generation(生命周期较长)。最后,tenured genera
-tion 满之后触发major collection。major collection(full GC)会触发整个heap的回收,包括回收
young generation。pamanet generation 区域比较稳定,主要存放classloader信息。

young generation 有eden、2个survivor区域组成。其中一个survivor区域一直是空的,是eden区域和另
一个survivor区域在下一次copy collection后活着的object的目的地。object在survivor区域被复制直
到转移到tenured区。

我们要尽量减少Full GC的次数(tenured generation一般比较大,手机的时间较长,频繁的Full GC会导
致应用的性能受到严重的影响。)

堆内存GC
JVM(采用分代回收的策略),用较高的频率对年轻的对象进行YGC,而对年老对象(turned generation)
较少(tenured generation满了以后才进行)进行Full GC。这样就不需要每次GC都将内存中所有对象都
检查一遍。

非堆内存不GC
GC不会在主程序运行期对PermGen space进行清理,所以如果你的应用中有很多Class(特别是动态生成类
,当然permgen space存放的内容不仅限于类)的话,就很可能出现PermGen Space错误。

内存申请、对象衰老过程
一、内存申请过程
1.JVM会试图为相关Java对象在Eden中初始化一块内存区域。
2.当Eden空间足够时,内存申请结束。否则到下一步;
3.JVM试图释放在Eden中所有不活跃的对象(minor collection),释放后若Eden空间仍然不
足以放入新对象,则试图将部分Eden中活跃对象放入Survivor区。
4.Survivor区被用来作为Eden及old的中间交换区域,当old区空间足够时,Survivor区的对
象会被移到old区,否则会被保留在Survivor区;
5.当old区空间不够时,JVM会在old区进行major collection;
6.完全垃圾收集后,若Survivor及old区仍然无法存放从Eden复制过来的部分对象,导致JVM
无法在Eden区为新对象创建内存区域,则出现"Out Of memory"错误

二、对象衰老过程
1、新创建的对象的内存都分配自eden。Minor collection的过程就是将eden和再用survivor
space中的活对象copy到空闲survivor space中。对象在young generation里经历了一定次数
的minor collection后,就会被移动到old generation 中,称为
tenuring。

2、GC触发条件
GC类型 触发条件 触发时发生了什么

YGC eden空间不足 清空Eden+from survivor中
所有noref的对象占用的内存
将eden+from sur中所与存活
的对象copy到to sur中
一些对象将晋升到old中:
to sur放不下的存活次数超过
turning threshhold中的重新
计算tenuring threshold
(serial parallel GC会触发
此项)
重新调整Eden和from的大小
(parallel GC会触发此项)

FGC old空间不足 清空heap中no ref的对象
perm空间不足 permgen中已经被卸载的
显示调用System.GC,RMI等的定时触发 classloader中加载的class
YGC时的悲观策略 信息
DUMP live的内存信息时(jmap -dump:live) 如配置了CollectGenFirst,
则先触发YGC(针对serial GC)
如配置了ScavengeBeforeFullGC,
则先触发YGC(serial GC

permanent generation空间不足会引发Full GC,仍然不够会引发PermGenSpace错误。
0 0
原创粉丝点击