做网站视频存储在哪里,一屏网站模板下载 迅雷下载 迅雷下载地址,重庆网络公司招聘,wordpress免费编辑器开源推荐推荐一款一站式性能监控工具(开源项目)Pepper-Metrics是跟一位同事一起开发的开源组件#xff0c;主要功能是通过比较轻量的方式与常用开源组件(jedis/mybatis/motan/dubbo/servlet)集成#xff0c;收集并计算metrics#xff0c;并支持输出到日志及转换成多种时序数…开源推荐推荐一款一站式性能监控工具(开源项目)Pepper-Metrics是跟一位同事一起开发的开源组件主要功能是通过比较轻量的方式与常用开源组件(jedis/mybatis/motan/dubbo/servlet)集成收集并计算metrics并支持输出到日志及转换成多种时序数据库兼容数据格式配套的grafana dashboard友好的进行展示。项目当中原理文档齐全且全部基于SPI设计的可扩展式架构方便的开发新插件。另有一个基于docker-compose的独立demo项目可以快速启动一套demo示例查看效果https://github.com/zrbcool/pepper-metrics-demo。如果大家觉得有用的话麻烦给个star也欢迎大家参与开发谢谢)进入正题...GC的出现解放了程序员需要手动回收内存的苦恼但我们也是要了解GC的知己知彼百战不殆嘛。常见的GC回收算法主要包括引用计数算法、可达性分析法、标记清除算法、复制算法、标记压缩算法、分代算法以及分区算法。其中引用计数法和可达性分析法用于判定一个对象是否可以回收其他的算法为具体执行GC时的算法。今天来聊聊可达性分析法并说明一下什么样的对象才是真正可以被回收的。在介绍引用计数法的时候我们提到了此种算法的循环引用的缺陷所以Java没有使用此种算法。那Java使用的是啥算法来标记一个对象是否是垃圾对象呢Java是通过判断一个对象是否可触及以及一个对象的引用类型(强引用、软引用、弱引用、虚引用)来决定是否回收这个对象。本文将根据上述分为两部分进行介绍。最后会简单介绍一下GC回收过程中保证数据一致性的方法Stop the World1 如何判断一个对象是否可触及判断是否可触及包含两个要素 通过可达性分析该对象到GC Root不可达如果不可达会进行第一次标记。 已经丧失自救机会如果没有自救机会会进行第二次标记此时该对象可回收。1.1 可达性分析可达性分析法定义了一系列称为GC Roots的对象作为起始点从这个起点开始向下搜索每一条可达路径称为引用链当一个对象没有任意一条引用链可以到达GC Roots时那么就对这个对象进行第一次可回收标记。那么什么是GC Root呢可以理解为由堆外指向堆内的引用。那么都有哪些对象可以作为GC Roots呢 包括如下几种 代码中某一方法中的局部变量 类变量(静态变量) 常量 本地方法栈中引用的对象 * 已启动且未停止的线程下面以一段代码来简单说明一下前三类class Test {private static A a new A(); // 静态变量 public static final String CONTANT I am a string; // 常量public static void main(String[] args) {A innerA new A(); // 局部变量 }}class A {...}这段代码的运行时内存图示如下首先类加载器加载Test类会初始化静态变量a将常量引用指向常量池中的字符串完成Test类的加载然后main方法执行main方法会入虚拟机方法栈执行main方法会在堆中创建A的对象并赋值给局部变量innerA。此时GC Roots状态如下当main方法执行完出栈后变为第三个对象已经没有引用链可达GC Root此时第三个对象被第一次标记。1.2 对象的自救一个被可达性分析标记为可回收的对象是有机会进行自救的。前提是覆写了Object的finalize()方法且GC还没有执行该对象的finalize()方法。先来看一下finalize方法的定义/*** Called by the garbage collector on an object when garbage collection* determines that there are no more references to the object.* A subclass overrides the {code finalize} method to dispose of* system resources or to perform other cleanup.* * The general contract of {code finalize} is that it is invoked* if and when the Java™ virtual* machine has determined that there is no longer any* means by which this object can be accessed by any thread that has* not yet died, except as a result of an action taken by the* finalization of some other object or class which is ready to be* finalized. The {code finalize} method may take any action, including* making this object available again to other threads; the usual purpose* of {code finalize}, however, is to perform cleanup actions before* the object is irrevocably discarded. For example, the finalize method* for an object that represents an input/output connection might perform* explicit I/O transactions to break the connection before the object is* permanently discarded.* * The {code finalize} method of class {code Object} performs no* special action; it simply returns normally. Subclasses of* {code Object} may override this definition.* * The Java programming language does not guarantee which thread will* invoke the {code finalize} method for any given object. It is* guaranteed, however, that the thread that invokes finalize will not* be holding any user-visible synchronization locks when finalize is* invoked. If an uncaught exception is thrown by the finalize method,* the exception is ignored and finalization of that object terminates.* * After the {code finalize} method has been invoked for an object, no* further action is taken until the Java virtual machine has again* determined that there is no longer any means by which this object can* be accessed by any thread that has not yet died, including possible* actions by other objects or classes which are ready to be finalized,* at which point the object may be discarded.* * The {code finalize} method is never invoked more than once by a Java* virtual machine for any given object.* * Any exception thrown by the {code finalize} method causes* the finalization of this object to be halted, but is otherwise* ignored.** throws Throwable the {code Exception} raised by this method* see java.lang.ref.WeakReference* see java.lang.ref.PhantomReference* jls 12.6 Finalization of Class Instances*/protected void finalize() throws Throwable { }大致翻译一下前两段当GC判定某一对象不再通过任一形式被引用时GC会调用该对象的finalize方法。方法执行时可以进行任何操作包括将这个对象再次赋值给某一变量引用但其主要目的还是做一些对象的清除操作。其实在finalize方法中只要将这个对象的引用(this)再次赋值给某一变量这个对象就可以自救。如果一个对象在finalize阶段也没有完成自救那么就真的要被回收了。下面演示一个自救的例子public class SaveMe {public static SaveMe saveMe;public static void main(String[] args) throws InterruptedException {saveMe new SaveMe();saveMe null; // 取消引用经过可达性分析上面new出来的对象不再可达GC Root System.gc(); // 第一次GC会执行finalize方法 Thread.sleep(1000);if (saveMe null) {System.out.println(对象为null);} else {System.out.println(对象不为null);}// 经过上面的过程对象已经自救了这里再次将其引用置空 saveMe null;System.gc(); // 不会再执行finalize方法没有机会自救了 Thread.sleep(1000);if (saveMe null) {System.out.println(对象为null);} else {System.out.println(对象不为null);}}// finalize方法全局只会执行一次 Overrideprotected void finalize() throws Throwable {super.finalize();saveMe this; // 进行自救 }}上述代码很简明可根据注释理解。代码执行结果如下2 不同引用类型的回收Java中有四种引用类型引用强度由强到弱强引用、软引用、弱引用、虚引用。针对不同的引用类型GC的回收策略不同。2.1 强引用通过关键字new的对象就是强引用对象强引用指向的对象任何时候都不会被回收宁愿OOM也不会回收。2.2 软引用如果一个对象持有软引用那么当JVM堆空间不足时会被回收。一个类的软引用可以通过java.lang.ref.SoftReference持有。2.3 弱引用如果一个对象持有弱引用那么在GC时只要发现弱引用对象就会被回收。一个类的弱引用可以通过java.lang.ref.WeakReference持有。2.4 虚引用几乎和没有一样随时可以被回收。通过PhantomReference持有。3 Stop the World问题的出现如果程序一边执行一边进行可达性分析的标记操作那么有可能刚标记完一个对象这个对象又再次被赋值给其他的引用。这样就有可能回收掉正在使用的对象。解决这个问题的方式就是Stop the World(STW)STW会在所有线程到达一个安全点时暂停掉所有应用线程的执行然后开始专心的标记垃圾对象。这样就保证了数据的一致性不会导致误回收。