流浪猫狗救助网站开发设计,建设一个网站多钱,做招商网站的前景怎么样,软件开发行业发展前景常见GC算法
引用计数法: 每个对象都有一个计数器, 对象被引用一次, 计数器1, 当对象引用失败一次. 计数器-1, 当对象计数器等于0, 说明对象没有被应用, 就可GC
优: 运行过程中, 可随时检查对象计数器, 进行GC, 且GC过程, 应用无需暂停, 执行速度快(单个对象GC不会影响其他对…常见GC算法
引用计数法: 每个对象都有一个计数器, 对象被引用一次, 计数器1, 当对象引用失败一次. 计数器-1, 当对象计数器等于0, 说明对象没有被应用, 就可GC
优: 运行过程中, 可随时检查对象计数器, 进行GC, 且GC过程, 应用无需暂停, 执行速度快(单个对象GC不会影响其他对象), 内存不足, OOM
缺: 存在循环引用问题(A引用B, B引用A, Anull, Bnull. A,B永远不会GC), 随时都在GC, 占用CPU标记清除: 先标记( 从root进行可达性分析, 标记被引用的对象), 再清除(清除那些没被引用的对象)
优; 解决循环引用问题
缺: 效率低下, 需要遍历所有对象, 碎片化严重, 清理出来的内存不连续, 当new大对象时, 容易爆OOM 标记压缩: 标记需要回收的区域, 进行回收, 将碎片化的空间进行压缩
优: 解决标记清除的碎片化问题
缺: 需要移动内存位置, 效率降低复制算法: 将空间一分为二(只使用其中一块空间进行存储), 进行清除的时候, 将存活对象复制到另外一块空间, 原本的空间全部清除, 解决移动内存问题
优: 解决标记清除存在的内存移动问题
缺: 对空间的浪费较为严重, 不适用内存空间垃圾较少的情况复制算法在JVM年轻代的应用 1. GC开始前, 对象分布于Eden, s0区, s1区为空
2. GC开始, Eden中的存活对象全部复制到s1中, s0区中存活对象根据他们的年龄值决定去向使用-XX:MaxTenuringThreshold设置年龄阈值, 超过该阈值, s0中对象移到老年代, 未达到, 对象则移动到s1中
3. GC完成, 清空Eden, s0区域, s0与s1交换角色, 重复步骤1, 直到s1被填满, 然后将s1中对象全部移到老年代中
优: 垃圾对象较多时, 效率高, 无碎片化
缺: 垃圾较少, 不适用, 如:老年代, s0/s1一个时刻只能使用其中一块, 内存使用率低分代算法: 年轻代采用复制清除, 老年代使用标记清除/压缩
垃圾收集器及内存分配
串行垃圾收集器: GC过程, 只有一个线程工作, 且应用要停止运行(Stop-the-world), 等待GC完成.
/*** 测试GC收集器* author regotto*/
public class GcTest {public static void main(String[] args) {ArrayListObject objects new ArrayList();while (true) {if (System.currentTimeMillis() % 2 0) {//产生大量废弃对象objects.clear();} else {for (int i 0; i 10000; i) {Properties properties new Properties();properties.put(key: i, value: System.currentTimeMillis());objects.add(properties);}}try {Thread.sleep(new Random().nextInt(100));} catch (InterruptedException e) {e.printStackTrace();}}}
}设置VM Optional: 使用串行GC器, 打印GC细节 运行结果如下: 日志解读(使用第一行数据):
GC: 年轻代GC; Full GC: 所有空间全部GC
DefNew: 使用串行GC器
4416k - 512k(4928k): GC前年轻代对象占4416k空间, GC年轻代对象占512k空间, 总共4928k空间
0.0019950secs: GC花费时间
7318k - 3975k(15872k): 堆空间GC情况并行垃圾回收器: 在串行GC的基础上, 变为多线程进行GC操作(存在Stop-the-world), 其余与串行GC一样 ParNew垃圾收集器 只能在年轻代工作(只是将串行GC变为并行GC), 使用-XX:UseParNewGC设置, 老年代依旧采用串行GC 测试代码在上一个代码的基础上修改VM options 运行过程中, 发现相比于SerialGC, ParNew在GC上存在一定的提升ParallelGC垃圾收集器 与ParNew一样, 新增多个与吞吐量相关的参数, 操作更加灵活
-XX:UseParallelGC 年轻代使用ParallelGC垃圾回收器老年代使用串行回收器。
-XX:UseParallelOldGC 年轻代使用ParallelGC垃圾回收器老年代使用ParallelOldGC垃圾回收器。
-XX:MaxGCPauseMillis 设置最大的垃圾收集时的停顿时间单位为毫秒 需要注意的是ParallelGC为了达到设置的停顿时间可能会调整堆大小或其他 的参数如果堆的大小设置的较小就会导致GC工作变得很频繁反而可能会 影响到性能。 该参数使用需谨慎。
-XX:GCTimeRatio 设置垃圾回收时间占程序运行时间的百分比公式为1/(1n)。 它的值为0~100之间的数字默认值为99也就是垃圾回收时间不能超过1%
-XX:UseAdaptiveSizePolicy 自适应GC模式垃圾回收器将自动调整年轻代、老年代等参数达到吞吐量、 堆大小、停顿时间之间的平衡。 一般用于手动调整参数比较困难的场景让收集器自动进行调整。 测试代码与前一个一样, 只修改VM options, 运行结果如下:
CMS垃圾处理器 CMS(Concurrent Mark Sweep): 针对老年代(对老年代GC进行改进), 使用标记清除算法, -XX:UseConcurrentMarkSweepGC设置. 执行过程如下:
InitialMarking: 标记root, 出现Stop-the-world
Marking: 标记对象, 与应用线程同时运行
preclean: 预清理, 与应用线程同时运行
finalMarking: 再次标记, 由于与应用线程同时运行, 前期的标记并不能解决问题, 此过程出现Stop-the-world
sweeping: 并发清除, 与应用线程同时运行
resizing: 调整堆大小, 清理碎片, 压缩空间
resetting: 重置, 等待触发下一次CMS, 与用户线程同时运行程序打印的日志也是按照上面的流程, 程序运行结果如下:
G1垃圾收集器(jdk1.7使用)
G1取消传统的新生代, 老年代物理划分, 将内存空间变为若干个区域, 每个区域包含逻辑上的新生代, 老年代. G1存在YoungGC, MixedGC, FullGC, 在不同的条件下触发
优: 每一块区域存在多种状态(Old, Eden, Humongous, Survivor)解决碎片化问题, 即使在正常处理过程中, 都能解决内存压缩问题G1的YoungGC
Eden区空间耗尽触发, EdenGC, Eden中数据移动到Survivor区(Survivor满了, 数据移动到新的Survivor区, 部分数据移动到Old区), 部分数据移动到Old区, 当前Eden清空, 变为未使用区
RememberSet(记忆集合)
RememberSet解决新生代寻找根对象的问题, 每一个区域初始化都生成一个RememberSet, 该集合保存其他对象引用我的记录, 扫描RememberSet就能得出对象之间的引用关系, 而不再需要对新生代, 老年代中所有对象进行扫描.
G1的MixedGC
为避免堆内存被耗尽, JVM启动MixedGC, 回收所有的Young区, 回收部分Old区(MixedGC不是FullGC). 使用-XX:InitiatingHeapOccupancyPercentn(老年代占整个堆大小百分比阈值) 决定MixedGC什么时候触发 MixedGC分为2个步骤: 全局并发标记(前5个步骤), 拷贝存活对象(第6个步骤)
G1相关参数
-XX:UseG1GC 使用 G1 垃圾收集器
-XX:MaxGCPauseMillis 设置期望达到的最大GC停顿时间指标JVM会尽力实现但不保证达到默认 值是 200 毫秒。
-XX:G1HeapRegionSizen 设置的 G1 区域的大小。值是 2 的幂范围是 1 MB 到 32 MB 之间。目标是根 据最小的 Java 堆大小划分出约 2048 个区域。 默认是堆内存的1/2000。
-XX:ParallelGCThreadsn 设置 STW 工作线程数的值。将 n 的值设置为逻辑处理器的数量。n 的值与逻辑 处理器的数量相同最多为 8。
-XX:ConcGCThreadsn 设置并行标记的线程数。将 n 设置为并行垃圾回收线程数 (ParallelGCThreads) 的 1/4 左右。
-XX:InitiatingHeapOccupancyPercentn 设置触发标记周期的 Java 堆占用率阈值。默认占用率是整个 Java 堆的 45%。G1日志输出参数
‐XX:PrintGC 输出GC日志
‐XX:PrintGCDetails 输出GC的详细日志
‐XX:PrintGCTimeStamps 输出GC的时间戳以基准时间的形式
‐XX:PrintGCDateStamps 输出GC的时间戳以日期的形式如 2013‐05‐ 04T21:53:59.2340800
‐XX:PrintHeapAtGC 在进行GC的前后打印出堆的信息
‐Xloggc:../logs/gc.log 日志文件的输出路径测试 代码运行完毕自动将GC日志输入到项目下的gc.log中 使用GC Easy进行分析(http://gceasy.io) 将gc.log上传该网站, 就能进行GC分析, 获取分析报告