[置顶] GC
2017-10-27 01:39
92 查看
GC
gc:java的垃圾回收机制在java中,内存的分配是由程序完成的,而内存的释放是由GC完成
调用System类的静态方法gc()可以进行垃圾回收,但它只是向JVM发出一个申请,到底是否真正执行垃圾收集,一切都是个未知数
垃圾回收的三种算法
标记清除算法:
标记阶段:先通过根节点,标记所有从根节点开始的对象,未标记的未垃圾对象
清除阶段:清除所有未标记的对象
缺点:标记和清除的效率都不高
清除之后会产生大量不连续的内存碎片,不连续的内存空间使用效率比较低
复制算法:(新生代使用的算法)
将原有的内存空间分为两块,每次只使用其中的一块,在垃圾回收时,将正在使用的内存块中的存活的对象复制到未使用的内存块中,然后清除正在使用的内存块中的所有对象
标记整理算法:(老年代使用的算法)
标记阶段:先通过根节点,标记所有从根节点开始的可达对象,未被标记的为垃圾对象
整理阶段:将所有存活的对象压缩到内存的一段,之后清理边界所有的空间
此外还有个古老的算法:引用计算法,其核心是对象在被引用时引用计数+1,而当引用不再使用时引用计数-1,当一个对象的引用计数为0时,则说明它将来不再被引用,因此可以释放对应的内存空间
三种算法比较
效率:复制算法>标记整理>标记清除(只是简单比较时间复杂度,实际情况不一定如此)
内存整齐度:复制算法=标记整理>标记清除
内存利用率:标记整理=标记清除>复制算法
GC引用可达性分析算法中,可作为GC Roots的对象
java虚拟机栈中的对象
方法区中的静态成员
方法区中的常量引用对象
本地方法区中的JNI(Native方法)引用对象
GC的分代回收
新生代:(复制算法 GC:minor gc)
在方法中new一个对象,在这个方法调用完毕后,对象就会被回收,这就是一个典型的新生代对象。
新生代存放生命周期很短的对象,这部分对象在GC的时候很多已经是非活动对象,因此采用复制算法,只需将少量的存活对象copy到to space,存活越少,效率越高
新生代又分为:
eden:每当对象创建的时候,总陪分配到这个区域
survivor1:复制算法中的from space
survivor2:复制算法中的to space
Hotspot默认将Eden区和两个survivor区按照8:2的比例划分
老年代:(标记整理算法 GC:major gc也叫full gc)
生命周期长,在新生代中经过多次minor gc依旧存活的对象。survivor空间不够用时,需要依赖老年代进行分配担保,所有大对象直接进入老年代。老年代区域比较大,需要时间长
永久代:(即方法区)
存放class信息,方法信息,常量池,静态变量
也会发生gc,这里的gc主要是对常量池的回收和对类的卸载
minor gc 与full gc
minor gc是新生代的垃圾回收机制,复制算法,调用频繁,回收速度快
full gc是老年代的垃圾回收机制,标记整理算法,调用不频繁,回收速度慢
full gc发生的次数不会有minor gc那么频繁,但Time(full gc)>Time(minor gc)
当eden满了,就minor gc
当Eden+from space空间大于老年代剩余空间时,就会full gc
垃圾收集器
Serial收集器:单线程独占
单线程收集器,不是只能使用一个CPU。在进行垃圾收集时,必须暂停其他所有的工作线程,直到收集结束
新生代–复制算法,老年代–标记整理算法
简单高效,client模式下默认的新生代收集器
ParNew收集器:多线程独占
ParNew收集器是Serial收集器的多线程版本
新生代–复制算法,老年代–标记整理算法
server模式下首选新生代收集器
ParNew S
9cf1
canvenge收集器:
类似ParNew,但更加关注吞吐量
G1收集器:
当今收集器发展的最前沿成果之一。对垃圾回收进行了划分优先级的操作,优先级的回收方式保证了他的高效率
最大的优点是结合了空间整合,不会产生大量的碎片,也降低了进行gc的频率
CMS收集器: 多线程非独占
使用的是标记清除算法
一种以获得最短回收停顿时间为目标的收集器,适用于互联网站和B/S系统的服务器上
java中的内存泄漏
在Java中,内存泄漏就是存在一些被分配的对象,这些对象不会被GC回收,但它们却占用内存
这些对象有两个特点:
对象是可达的
对象是无用的
例子:循环申请Object对象并放入一个Vector中。如果仅仅释放引用本身,那么Vector仍然引用该对象,这个对象对于GC来说是不可回收的。如果对象加入到Vector后还要将其删除,最简单的办法就是将Vector对象置为null
Vector v = new Vector(); for (int i = 0; i < 100; i++) { Object o = new Object(); v.add(o); o = null; } v = null;
物理连接:例如数据库和网络连接,除非显示的关闭了连接,否则不会自动被GC回收。数据库的Connection这些连接是独立于JVM的,对于ResultSet 和Statement对象可以不进行显示回收,但Connection一定要显示回收,因为Connection在任何时候都无法自动回收,而Connection一旦回收,ResultSet和Statement就会立即为null。但是如果使用的是连接池的情况就不一样,处了要显示关闭连接,还要显示关闭ResultSet和Statement对象
单例模式:因为单例对象初始化后将在JVM的整个生命周期内存在,如果它持有一个外部对象的引用,那么这个外部对象就不能被回收,从而导致内存泄漏。如果这个外部对象还持有其他对象的引用,那么泄露更严重
相关文章推荐
- [置顶] 深入理解JVM的内存结构及GC机制
- [置顶] HBase G1 GC 调优,GC时间缩短为原来的20%左右。
- [置顶] Deep Forest: gcForest论文知识梳理
- [置顶] 深入理解JVM 一GC(下) G1 Garbage Collector
- [置顶] 使用VisualVM监控远程服务器JVM+原创离线安装VisualGC插件
- [置顶] JVM 的GC回收算法----G1
- [置顶] JAVA GC 与 内存分配策略
- [置顶] 【Android okhttp源码解析 四】任务调度核心类dispatcher解析
- [置顶] js中this的使用
- [置顶] matlab_N皇后问题的解决
- [置顶] 中国联通517活动-沃福卡-技术分解实现方案
- [置顶] 常用JQuery插件整理收藏分享
- [置顶]c# 设计模式(2)结构型
- [置顶] 优秀IT技术文章集(最新)(高质量)
- [置顶] SpringBoot 使用Mybatis-Generator自动生成代码
- [置顶] kubernetes创建资源对象yaml文件例子--pod
- [置顶] LeetCode--Intersection of Two Linked Lists (两个链表的交点)Python
- 144 Linux使用jstat命令查看jvm的GC情况
- [置顶] 史上最全的MonkeyRunner自动化测试从入门到精通(9)
- vc将窗口置顶的SetWindowPos()函数以及相关