当前位置: 首页 > news >正文

深圳建站的公司如何自己设计logo图标

深圳建站的公司,如何自己设计logo图标,公司网站.可以自己做吗,网站建设500元Java中一共有4种引用类型(其实还有一些其他的引用类型比如FinalReference)#xff1a;强引用、软引用、弱引用、虚引用。 其中强引用就是我们经常使用的Object a new Object(); 这样的形式#xff0c;在Java中并没有对应的Reference类。 本篇文章主要是分析软引用、弱引用、… Java中一共有4种引用类型(其实还有一些其他的引用类型比如FinalReference)强引用、软引用、弱引用、虚引用。 其中强引用就是我们经常使用的Object a new Object(); 这样的形式在Java中并没有对应的Reference类。 本篇文章主要是分析软引用、弱引用、虚引用的实现这三种引用类型都是继承于Reference这个类主要逻辑也在Reference中。 问题 在分析前先抛几个问题 1.网上大多数文章对于软引用的介绍是在内存不足的时候才会被回收那内存不足是怎么定义的什么才叫内存不足 2.网上大多数文章对于虚引用的介绍是形同虚设虚引用并不会决定对象的生命周期。主要用来跟踪对象被垃圾回收器回收的活动。真的是这样吗 3.虚引用在Jdk中有哪些场景下用到了呢 Reference 我们先看下Reference.java中的几个字段 public abstract class ReferenceT {    //引用的对象    private T referent;            //回收队列由使用者在Reference的构造函数中指定    volatile ReferenceQueue? super T queue;     //当该引用被加入到queue中的时候该字段被设置为queue中的下一个元素以形成链表结构    volatile Reference next;    //在GC时JVM底层会维护一个叫DiscoveredList的链表存放的是Reference对象discovered字段指向的就是链表中的下一个元素由JVM设置    transient private ReferenceT discovered;      //进行线程同步的锁对象    static private class Lock { }    private static Lock lock  new Lock();    //等待加入queue的Reference对象在GC时由JVM设置会有一个java层的线程(ReferenceHandler)源源不断的从pending中提取元素加入到queue    private static ReferenceObject pending  null;} 一个Reference对象的生命周期如下 主要分为Native层和Java层两个部分。 Native层在GC时将需要被回收的Reference对象加入到DiscoveredList中代码在referenceProcessor.cpp中process_discovered_references方法然后将DiscoveredList的元素移动到PendingList中代码在referenceProcessor.cpp中enqueue_discovered_ref_helper方法,PendingList的队首就是Reference类中的pending对象。 看看Java层的代码 private static class ReferenceHandler extends Thread {         ...        public void run() {            while (true) {                tryHandlePending(true);            }        }  } static boolean tryHandlePending(boolean waitForNotify) {        ReferenceObject r;        Cleaner c;        try {            synchronized (lock) {                if (pending ! null) {                    r  pending;                     //如果是Cleaner对象则记录下来下面做特殊处理                    c  r instanceof Cleaner ? (Cleaner) r : null;                    //指向PendingList的下一个对象                    pending  r.discovered;                    r.discovered  null;                } else {                   //如果pending为null就先等待当有对象加入到PendingList中时jvm会执行notify                    if (waitForNotify) {                        lock.wait();                    }                    // retry if waited                    return waitForNotify;                }            }        }         ...        // 如果时CLeaner对象则调用clean方法进行资源回收        if (c ! null) {            c.clean();            return true;        }        //将Reference加入到ReferenceQueue开发者可以通过从ReferenceQueue中poll元素感知到对象被回收的事件。        ReferenceQueue? super Object q  r.queue;        if (q ! ReferenceQueue.NULL) q.enqueue(r);        return true; } 流程比较简单就是源源不断的从PendingList中提取出元素然后将其加入到ReferenceQueue中去开发者可以通过从ReferenceQueue中poll元素感知到对象被回收的事件。 另外需要注意的是对于Cleaner类型继承自虚引用的对象会有额外的处理在其指向的对象被回收时会调用clean方法该方法主要是用来做对应的资源回收在堆外内存DirectByteBuffer中就是用Cleaner进行堆外内存的回收这也是虚引用在java中的典型应用。 看完了Reference的实现再看看几个实现类里各自有什么不同。 SoftReference public class SoftReferenceT extends ReferenceT {    static private long clock;    private long timestamp;    public SoftReference(T referent) {        super(referent);        this.timestamp  clock;    }    public SoftReference(T referent, ReferenceQueue? super T q) {        super(referent, q);        this.timestamp  clock;    }    public T get() {        T o  super.get();        if (o ! null  this.timestamp ! clock)            this.timestamp  clock;        return o;    }} 软引用的实现很简单就多了两个字段clock和timestamp。clock是个静态变量每次GC时都会将该字段设置成当前时间。timestamp字段则会在每次调用get方法时将其赋值为clock如果不相等且对象没被回收。 那这两个字段的作用是什么呢****这和软引用在内存不够的时候才被回收又有什么关系呢 这些还得看JVM的源码才行因为决定对象是否需要被回收都是在GC中实现的。 size_tReferenceProcessor::process_discovered_reflist(  DiscoveredList               refs_lists[],  ReferencePolicy*             policy,  bool                         clear_referent,  BoolObjectClosure*           is_alive,  OopClosure*                  keep_alive,  VoidClosure*                 complete_gc,  AbstractRefProcTaskExecutor* task_executor){ ...   //还记得上文提到过的DiscoveredList吗?refs_lists就是DiscoveredList。   //对于DiscoveredList的处理分为几个阶段SoftReference的处理就在第一阶段 ...      for (uint i  0; i  _max_num_q; i) {        process_phase1(refs_lists[i], policy,                       is_alive, keep_alive, complete_gc);      } ...}//该阶段的主要目的就是当内存足够时将对应的SoftReference从refs_list中移除。voidReferenceProcessor::process_phase1(DiscoveredList    refs_list,                                   ReferencePolicy*   policy,                                   BoolObjectClosure* is_alive,                                   OopClosure*        keep_alive,                                   VoidClosure*       complete_gc) {  DiscoveredListIterator iter(refs_list, keep_alive, is_alive);  // Decide which softly reachable refs should be kept alive.  while (iter.has_next()) {    iter.load_ptrs(DEBUG_ONLY(!discovery_is_atomic() /* allow_null_referent */));    //判断引用的对象是否存活    bool referent_is_dead  (iter.referent() ! NULL)  !iter.is_referent_alive();    //如果引用的对象已经不存活了则会去调用对应的ReferencePolicy判断该对象是不时要被回收    if (referent_is_dead         !policy-should_clear_reference(iter.obj(), _soft_ref_timestamp_clock)) {      if (TraceReferenceGC) {        gclog_or_tty-print_cr(Dropping reference ( INTPTR_FORMAT : %s  ) by policy,                               (void *)iter.obj(), iter.obj()-klass()-internal_name());      }      // Remove Reference object from list      iter.remove();      // Make the Reference object active again      iter.make_active();      // keep the referent around      iter.make_referent_alive();      iter.move_to_next();    } else {      iter.next();    }  } ...} refs_lists中存放了本次GC发现的某种引用类型虚引用、软引用、弱引用等而process_discovered_reflist方法的作用就是将不需要被回收的对象从refs_lists移除掉refs_lists最后剩下的元素全是需要被回收的元素最后会将其第一个元素赋值给上文提到过的Reference.java#pending字段。 ReferencePolicy一共有4种实现NeverClearPolicyAlwaysClearPolicyLRUCurrentHeapPolicyLRUMaxHeapPolicy。 其中NeverClearPolicy永远返回false代表永远不回收SoftReference在JVM中该类没有被使用AlwaysClearPolicy则永远返回true在referenceProcessor.hpp#setup方法中中可以设置policy为AlwaysClearPolicy至于什么时候会用到AlwaysClearPolicy大家有兴趣可以自行研究。 LRUCurrentHeapPolicy和LRUMaxHeapPolicy的should_clear_reference方法则是完全相同 bool LRUMaxHeapPolicy::should_clear_reference(oop p,                                             jlong timestamp_clock) {  jlong interval  timestamp_clock - java_lang_ref_SoftReference::timestamp(p);  assert(interval  0, Sanity check);  // The interval will be zero if the ref was accessed since the last scavenge/gc.  if(interval  _max_interval) {    return false;  }  return true;} timestamp_clock就是SoftReference的静态字段clockjava_lang_ref_SoftReference::timestamp(p)对应是字段timestamp。如果上次GC后有调用SoftReference#getinterval值为0否则为若干次GC之间的时间差。 _max_interval则代表了一个临界值它的值在LRUCurrentHeapPolicy和LRUMaxHeapPolicy两种策略中有差异。 void LRUCurrentHeapPolicy::setup() {  _max_interval  (Universe::get_heap_free_at_last_gc() / M) * SoftRefLRUPolicyMSPerMB;  assert(_max_interval  0,Sanity check);}void LRUMaxHeapPolicy::setup() {  size_t max_heap  MaxHeapSize;  max_heap - Universe::get_heap_used_at_last_gc();  max_heap / M;  _max_interval  max_heap * SoftRefLRUPolicyMSPerMB;  assert(_max_interval  0,Sanity check);} 其中SoftRefLRUPolicyMSPerMB默认为1000前者的计算方法和上次GC后可用堆大小有关后者计算方法和堆大小-上次gc时堆使用大小有关。 看到这里你就知道SoftReference到底什么时候被被回收了它和使用的策略默认应该是LRUCurrentHeapPolicy堆可用大小该SoftReference上一次调用get方法的时间都有关系。 WeakReference public class WeakReferenceT extends ReferenceT {    public WeakReference(T referent) {        super(referent);    }    public WeakReference(T referent, ReferenceQueue? super T q) {        super(referent, q);    }} 可以看到WeakReference在Java层只是继承了Reference没有做任何的改动。那referent字段是什么时候被置为null的呢要搞清楚这个问题我们再看下上文提到过的process_discovered_reflist方法 size_tReferenceProcessor::process_discovered_reflist(  DiscoveredList               refs_lists[],  ReferencePolicy*             policy,  bool                         clear_referent,  BoolObjectClosure*           is_alive,  OopClosure*                  keep_alive,  VoidClosure*                 complete_gc,  AbstractRefProcTaskExecutor* task_executor){ ...  //Phase 1:将所有不存活但是还不能被回收的软引用从refs_lists中移除只有refs_lists为软引用的时候这里policy才不为null  if (policy ! NULL) {    if (mt_processing) {      RefProcPhase1Task phase1(*this, refs_lists, policy, true /*marks_oops_alive*/);      task_executor-execute(phase1);    } else {      for (uint i  0; i  _max_num_q; i) {        process_phase1(refs_lists[i], policy,                       is_alive, keep_alive, complete_gc);      }    }  } else { // policy  NULL    assert(refs_lists ! _discoveredSoftRefs,           Policy must be specified for soft references.);  }  // Phase 2:  // 移除所有指向对象还存活的引用  if (mt_processing) {    RefProcPhase2Task phase2(*this, refs_lists, !discovery_is_atomic() /*marks_oops_alive*/);    task_executor-execute(phase2);  } else {    for (uint i  0; i  _max_num_q; i) {      process_phase2(refs_lists[i], is_alive, keep_alive, complete_gc);    }  }  // Phase 3:  // 根据clear_referent的值决定是否将不存活对象回收  if (mt_processing) {    RefProcPhase3Task phase3(*this, refs_lists, clear_referent, true /*marks_oops_alive*/);    task_executor-execute(phase3);  } else {    for (uint i  0; i  _max_num_q; i) {      process_phase3(refs_lists[i], clear_referent,                     is_alive, keep_alive, complete_gc);    }  }  return total_list_count;}voidReferenceProcessor::process_phase3(DiscoveredList    refs_list,                                   bool               clear_referent,                                   BoolObjectClosure* is_alive,                                   OopClosure*        keep_alive,                                   VoidClosure*       complete_gc) {  ResourceMark rm;  DiscoveredListIterator iter(refs_list, keep_alive, is_alive);  while (iter.has_next()) {    iter.update_discovered();    iter.load_ptrs(DEBUG_ONLY(false /* allow_null_referent */));    if (clear_referent) {      // NULL out referent pointer      //将Reference的referent字段置为null之后会被GC回收      iter.clear_referent();    } else {      // keep the referent around      //标记引用的对象为存活该对象在这次GC将不会被回收      iter.make_referent_alive();    }    ...  }    ...} 不管是弱引用还是其他引用类型将字段referent置null的操作都发生在process_phase3中而具体行为是由clear_referent的值决定的。而clear_referent的值则和引用类型相关。 ReferenceProcessorStats ReferenceProcessor::process_discovered_references(  BoolObjectClosure*           is_alive,  OopClosure*                  keep_alive,  VoidClosure*                 complete_gc,  AbstractRefProcTaskExecutor* task_executor,  GCTimer*                     gc_timer) {  NOT_PRODUCT(verify_ok_to_handle_reflists());    ...  //process_discovered_reflist方法的第3个字段就是clear_referent  // Soft references  size_t soft_count  0;  {    GCTraceTime tt(SoftReference, trace_time, false, gc_timer);    soft_count       process_discovered_reflist(_discoveredSoftRefs, _current_soft_ref_policy, true,                                 is_alive, keep_alive, complete_gc, task_executor);  }  update_soft_ref_master_clock();  // Weak references  size_t weak_count  0;  {    GCTraceTime tt(WeakReference, trace_time, false, gc_timer);    weak_count       process_discovered_reflist(_discoveredWeakRefs, NULL, true,                                 is_alive, keep_alive, complete_gc, task_executor);  }  // Final references  size_t final_count  0;  {    GCTraceTime tt(FinalReference, trace_time, false, gc_timer);    final_count       process_discovered_reflist(_discoveredFinalRefs, NULL, false,                                 is_alive, keep_alive, complete_gc, task_executor);  }  // Phantom references  size_t phantom_count  0;  {    GCTraceTime tt(PhantomReference, trace_time, false, gc_timer);    phantom_count       process_discovered_reflist(_discoveredPhantomRefs, NULL, false,                                 is_alive, keep_alive, complete_gc, task_executor);  }    ...} 可以看到对于Soft references和Weak references clear_referent字段传入的都是true这也符合我们的预期对象不可达后引用字段就会被置为null然后对象就会被回收对于软引用来说如果内存足够的话在Phase 1相关的引用就会从refs_list中被移除到Phase 3时refs_list为空集合。 但对于Final references和 Phantom referencesclear_referent字段传入的是false也就意味着被这两种引用类型引用的对象如果没有其他额外处理只要Reference对象还存活那引用的对象是不会被回收的。Final references和对象是否重写了finalize方法有关不在本文分析范围之内我们接下来看看Phantom references。 PhantomReference public class PhantomReferenceT extends ReferenceT {    public T get() {        return null;    }    public PhantomReference(T referent, ReferenceQueue? super T q) {        super(referent, q);    }} 可以看到虚引用的get方法永远返回null我们看个demo。  public static void demo() throws InterruptedException {        Object obj  new Object();        ReferenceQueueObject refQueue new ReferenceQueue();        PhantomReferenceObject phanRef new PhantomReference(obj, refQueue);        Object objg  phanRef.get();        //这里拿到的是null        System.out.println(objg);        //让obj变成垃圾        objnull;        System.gc();        Thread.sleep(3000);        //gc后会将phanRef加入到refQueue中        Reference? extends Object phanRefP  refQueue.remove();         //这里输出true        System.out.println(phanRefPphanRef);    } 从以上代码中可以看到虚引用能够在指向对象不可达时得到一个通知其实所有继承References的类都有这个功能需要注意的是GC完成后phanRef.referent依然指向之前创建Object也就是说Object对象一直没被回收 而造成这一现象的原因在上一小节末尾已经说了对于Final references和 Phantom referencesclear_referent字段传入的时false也就意味着被这两种引用类型引用的对象如果没有其他额外处理在GC中是不会被回收的。 对于虚引用来说从refQueue.remove();得到引用对象后可以调用clear方法强行解除引用和对象之间的关系使得对象下次可以GC时可以被回收掉。 总结 针对文章开头提出的几个问题看完分析我们已经能给出回答 1.我们经常在网上看到软引用的介绍是在内存不足的时候才会回收那内存不足是怎么定义的为什么才叫内存不足 软引用会在内存不足时被回收内存不足的定义和该引用对象get的时间以及当前堆可用内存大小都有关系计算公式在上文中也已经给出。 2.网上对于虚引用的介绍是形同虚设与其他几种引用都不同虚引用并不会决定对象的生命周期。主要用来跟踪对象被垃圾回收器回收的活动。真的是这样吗 严格的说虚引用是会影响对象生命周期的如果不做任何处理只要虚引用不被回收那其引用的对象永远不会被回收。所以一般来说从ReferenceQueue中获得PhantomReference对象后如果PhantomReference对象不会被回收的话比如被其他GC ROOT可达的对象引用需要调用clear方法解除PhantomReference和其引用对象的引用关系。 3.虚引用在Jdk中有哪些场景下用到了呢 DirectByteBuffer中是用虚引用的子类Cleaner.java来实现堆外内存回收的后续会写篇文章来说说堆外内存的里里外外。 来源github.com/farmerjohngit/myblog/issues/10 本文由 mdnice 多平台发布
http://www.w-s-a.com/news/411028/

相关文章:

  • 建设网站所需技术wordpress延时加载js
  • 网站建设沈阳搜云seo
  • 怎么申请免费的网站空间微信公众平台注册收费吗
  • 东营网站搭建最基本的网站设计
  • 网站建设技术的发展最近的国际新闻大事
  • 德州有名的网站建设公司网站如何做引流
  • 建设一个收入支出持平的网站网络推广计划书格式
  • 什么是网站黑链全球新冠疫苗接种率
  • 网站开发 chrome gimp网站不备案做seo没用
  • 织梦校园招生网站源码沪佳哪个好
  • 建设企业网站可信度软件产品如何做网站推广
  • 网站建设企业号助手贵阳景观设计公司
  • 网站开发第三方建设银行个人网站显示不了
  • 无锡兼职做网站郑州网站建设搜索优化
  • iis禁止通过ip访问网站品牌策划案例ppt
  • 电子商务网站建设实习seo黑帽优化
  • 如何做好网站建设销售闸北集团网站建设
  • 重庆装饰公司北京官网seo推广
  • 深圳网站设计灵点网络品牌网站充值接口
  • 建设书局 网站国内国际时事图片
  • 成都 网站建设培训学校屏蔽wordpress自带编辑器
  • 公司网站制作工作室中天建设集团有限公司第五建设公司
  • 网站的网页设计毕业设计苏州宣传册设计广告公司
  • 商城网站优化方案注册公司制作网站
  • 政务服务网站建设整改报告wordpress的导航代码
  • 图片素材网站建设做教育网站用什么颜色
  • 快站淘客中转页wordpress商业插件
  • 可信网站网站认证免费软件下载网站免费软件下载网站
  • 小学生网站制作最新域名网站
  • 奖励网站代码设计制作ppt时