您的位置:首页 > 其它

垃圾收集器与内存分配策略

2017-03-05 14:11 218 查看

1. 对象是否已死

对象是否存活算法:引用计数算法、可达性分析算法

1.1 引用计数算法

给对象中添加一个引用计数器,引用它时,计数器值就加1;当引用失效时,计数值就减1;任何时刻计数器为0的对象就是不可能再被使用的。

虚拟机未采用这种算法,主要是因为该算法很难解决对象之间相互循环引用问题。

1.2 可达性分析算法

基本思路为:通过一系列的称为:“GC Roots” 的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路称为引用链,当一个对象到GC Roots没有任何引用链相连(就是从GC Roots到这个对象不可达)时,则证明此对象是不可用的。

在Java语言可以做GC Roots的对象包括下面几种:

虚拟机栈中的引用的对象

方法区中类静态属性引用的对象。

方法区中常量引用的对象。

本地方法栈中(即Native方法)引用的对象。

1.3 引用类型

强引用

软引用

弱引用

虚引用

1.4 回收方法区

主要回收两部分内容:废弃常量和无用的类。

无用的类的确认条件:

该类所有的实例都已经被回收,也就是Java堆中不存在该类的任何实例。

加载该类的ClassLoader已经被回收。

该类对应的java.lang.class对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。

这里说的仅仅是“可以”,并不会必然回收。是否对类进行回收,可以通过-Xnoclassgc参数进行控制。

2. 垃圾收集算法

标记-清除算法:标记需要回收的对象,在标记完成后统一回收所有被标记的对象。

复制算法:将可用内存按容量划分为大小相等的两块,每次只使用其中的一块,当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。这种实现简单,运行高效。只是把内存缩小为原来的一半。一般使用该算法来回收新生代,同时不需要按照1:1比例来划分,而是把内存分为Eden空间和两块较小的Survivor空间,每次使用Eden和其中一块Survivor,当回收时,将Eden和Survivor中还存活的对象复制到另外一块Survivor上,最后清理掉Eden和已用过的Survivor空间。

标记-整理算法:标记过程仍然与‘标记-清除’一样,后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉边界以外的内存。

分代收集算法:根据对象存活周期的不同将内存划分为几块,一般分为新生代和老年代,这样就可以根据年代的特点采用最适当的收集算法。

3. 垃圾收集器

Serial收集器:针对新生代收集。

ParNew收集器:多线程收集,其他的与Serial没很大的区别,可以使用:-XX:+UseParNewGC来收集新生代;只有它能与CMS收集器配合工作。

Parallel Scavenge收集器: 新生代收集器,它的关注点是达到一个可控制的吞吐量;两个参数与吞吐量有关,-XX:MaxGCPauseMillis(控制最大垃圾收集器停顿时间)、-XX:GCTimeRation(直接设置吞吐量大小)。还有一个参数-XX:+UseAdaptiveSizePolicy值得关注,当这个参数打开后,不需要指定新生代的大小、Eden、Survior区的比例…虚拟机就会动态调整这些参数已提供最合适额停顿时间或者最大的吞吐量,然后只需设置好基本内存数据(-Xmx、-XX:MaxGCPauseMillis),这种方式称为自动调节策略。

Serial Old收集器:

并行(Parallel):指多条垃圾收集线程并行工作,但此时用户线程仍然处于等待状态。

并发(Concurrent):指用户线程与垃圾收集线程同时执行(但不一定是并行的,可能会交替进行),用户程序在继续运行,而垃圾收集程序运行于另一个CPU上。

Parallel Old

CMS(Concurrent Mark Sweep)

垃圾收集器参数

查看jvm参数

//查看 当前使用jdk的进程 下面这个5254为进程id; 在macox系统
ps -ef | grep java
501  5254   868   0 11:00下午

//查看当前jvm的参数
jcmd 868 VM.flags
-XX:InitialHeapSize=41943040 -XX:MaxHeapSize=536870912
-XX:MaxPermSize=268435456 -XX:+UseCompressedOops
-XX:+UseParallelGC

//显示系统内所有的java进程
jps -l
5482 sun.tools.jps.Jps
5440 org.jboss.modules.Main

//显示jvm配置信息
jinfo -flags 5440
-agentlib:jdwp=transport=dt_socket,suspend=y,address=localhost:60380 -Dprogram.name=JBossTools: JBoss AS 7.1 -Xms64m -Xmx512m -XX:MaxPermSize=256m -Dorg.jboss.resolver.warning=true -Djava.net.preferIPv4Stack=true -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000 -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true -Dorg.jboss.boot.log.file=/Users/zhangluxian/plusApp/jboss-as-7.1.1.Final/standalone/log/boot.log -Dlogging.configuration=file:/Users/zhangluxian/plusApp/jboss-as-7.1.1.Final/standalone/configuration/logging.properties -Djboss.home.dir=/Users/zhangluxian/plusApp/jboss-as-7.1.1.Final -Djboss.bind.address.management=localhost -Dfile.encoding=UTF-8


4. 内存分配与回收策略

大对象优先在Eden分配

大对象直接进入老年代

长期存活的对象进入老年代

动态对象年龄判定:如果在survivor空间中相同年龄的所有对象大小的综合大于Survior空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年底啊

空间分配担保
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: