在3358 www.Sina.com/http://www.Sina.com /对象中添加引用计算机,每增加一个引用处加一个,引用失效后减一个,计数器为0表示未使用对象
特点:实现简单,效率高,python、Microsoftcom等采用参考计数器算法管理内存。
缺点:对象之间的相互循环导致的引用问题很难解决。
常用的垃圾回收算法:通过确定一个对象是否能够通过节点连接到“gc root”,如果没有,则指示该对象是不可到达的对象,垃圾收集器将
特点: c#和java采用根搜索算法进行内存管理。
可以在java中用作GC根的对象包括:
a.java虚拟机堆栈(堆栈帧中的本地变量表)中引用的对象。
b .方法区域中类的静态属性引用的对象
c .方法区域中的常量引用对象。
d .本地方法堆栈引用该JNI本地方法的位置。
JVA虚拟机常规垃圾回收的算法1.引用计数算法
最基本的垃圾回收算法分为“标记”和“清除”两个阶段,在先标记的位置标记要回收的对象,标记完成后,批量回收所有标记的对象。
缺点)1)效率问题、标记和清除效率不高。
2 )清除会生成大量不连续的内存片段,在程序需要为大对象分配内存时找不到足够的连续内存,可能不得不提前触发垃圾回收操作。
2.跟搜索算法将内存分为两个大小相同的块,每次只使用其中一个,一个耗尽后,将仍然存在的对象复制到另一个块中,并一次清理掉之前已占用的空间
优点:分配内存时不需要考虑内存碎片,只需移动堆上的指针,按顺序分配即可,简单高效。
缺点:内存空间浪费大,一次只能使用当前可用内存空间一半的对象存活率高时,需要大量复制操作,效率低下。
1.标记-清除算法
标签整理是通过标签-清算改进的,上述标签-清算内存碎片化问题已在标签-整理中得到解决。 同样有标记阶段,标记所有需要回收的对象,但不是直接清理,而是将生存的对象移动到一端,然后在移动过程中清理可回收的对象。
优点:解决了内存碎片问题,效率远远高于复制算法,尤其是在存活率较高的情况下。
2.复制算法:
根据内存对象的生命周期,内存可以分为几个块。 java虚拟机通常将内存分为jkdzx层代和上一代,并且在创建新对象时通常会为jkdzx层代分配内存。 无论在jkdzx层代垃圾收集器中回收多少次仍存在的对象将移动到上一代。 或者,如果jkdzx层代没有将大对象分配给足够连续的内存空间,也会将其直接分配给上一代。
jvm垃圾收集器的内存结构
从图中可以看出,堆内存分为jkdzx代和较旧的年代,整个堆内存采用了按频段复制垃圾回收的算法。
3.标记-整理
使用复制标记-清理算法收集垃圾时,由于jkdzx世代存在许多生命周期较短的对象,因此不需要谈论量化部分(如jkdzx世代的容量),而是将jkdzx世代称为yedkf、surviid 其中,如上图所示,jkdzx代内存容量的默认比例为8:1:1。 survivor from和survivor to区域之一始终为空,只有yedkf和survior (即总容量的90% )用于为新对象的碰撞分配内存。 这样可以减少内存浪费。 如果jkdzx代内存空间分配不足,则仍存在的对象将分配给空的survior内存空间。 yedkf和非空白的survivor被标记回收,两个survivor交换使用。
jvm将jkdzx世代的垃圾回收称为Minor GC,次数频繁,每次的回收时间也短。
-Xmn设置jkdzx世代的内存大小。
4.分代收集算法
由于老年代存活率普遍较高,采用标记-整理算法进行垃圾收集效率更高。
jvm将老年代的垃圾回收称为MajorGC/Full GC,次数相对较少,每次回收时间也较长。
如果jkdzx层代没有足够的空间为对象分配内存,并且旧层代的内存也无法回收到足够的空间,则堆将引发OOM异常。
1.jkdzx代
1 .写满了古老的年代
2 .写满了永久的世代
3 .将显示并调用3.System.gc ()
4 .自上次GC以来,Heap的域分配策略发生了动态变化。
GC垃圾收集2.老年代
jkdzx代单线程收集器具有标记和清理为单线程、简单高效的优点。
Full GC触发条件:
上一代单线程单线程收集器、串行收集器
老年代版本。ParNew收集器(停止-复制算法)
jkdzx代收集器,可以认为是Serial收集器的多线程版本,在多核cpu下有着比Serial更好的表现。
Parallel scavenge收集器(停止-复制算法)
并行收集器,最求高吞吐量,高效利用CPU。吞吐量一般为99%,吞吐量=用户线程时间/(用户线程时间+GC时间)。适合后台应用对交互响应要求不高的场景。
Parallel Old收集器(停止-复制算法)
老年代的Parallel scavenge的收集器,并行收集,吞吐优先
Concurrent Mark Sweep 收集器(标记-清理算法)
高并发、低停顿,追求最短GC回收停顿时间,cpu占用比较高响应时间快,停顿短,多核cpu最求高响应时间的选择。
GC内存泄漏问题
1.静态集合HashMap、Vector等的使用最容易出现内存泄漏,这些静态变量的生命周期和应用程序一致,所有的对象都不能被释放。
2.各种数据连接、网络连接、io连接等没有显示的调用close关闭,不能被GC回收导致内存泄漏。
3.监听器的使用,在释放的对象没有删除相应的监听器也可能导致内存泄漏。
参考博客:深入理解java垃圾回收算法
深入理解java垃圾回收机制----