范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

一文搞懂JAVA中的引用

  介绍
  JAVA 中有 4 种类型的引用:
  - 强引用
  - 软引用
  - 弱引用
  - 虚引用
  这些引用仅在 垃圾收集器 管理它们的方式上有所不同。如果您从未听说过它们,则意味着您只使用过强的。了解其中的区别会对您有所帮助,尤其是当您需要存储临时对象并且不能   使用像 eHcache 或 Guava 这样的真正的缓存库时。
  由于这些类型与 JVM 垃圾收集器密切相关,因此我将简要回顾一些有关 JAVA 中垃圾收集的信息,然后介绍不同的类型。 垃圾收集器
  Java 和 C++ 之间的主要区别是 内存管理 。在 Java 中,开发人员不需要知道内存是如何工作的(但他应该知道!),因为 JVM 使用其垃圾收集器来处理这部分。
  当您创建一个对象时,它由 JVM 在其  堆中 分配。堆是内存中有限的空间。因此,JVM 经常需要删除对象以释放空间。为了销毁一个对象,JVM 需要知道这个对象是活跃的还是不活跃的。 如果一个对象被"垃圾收集根 "引用(传递地),则该对象仍在使用中。
  例如: 如果对象 C 被对象 B 引用,B 被对象 A 引用,A 被 垃圾回收根 引用,那么 C、B 和 A 被认为是活动的(情况 1)。 但是,如果 B 不再被 A 引用,则 C 和 B 不再处于活动状态并且可以被销毁(情况 2)。
  由于这篇文章不是关于垃圾收集器的,所以我不会深入解释,但仅供参考,有 4 种类型的垃圾收集器根: 局部   变量 活跃的 Java 线程 静态变量 JNI 引用 是包含本机代码的 Java 对象,而不是由 jvm 管理的内存
  Oracle 没有指定如何管理内存,因此每个 JVM 实现都有自己的一套算法。但想法总是一样的:
  – JVM 使用循环算法寻找非活动对象并标记它们
  – 标记的对象被终结(调用 finalize() 方法)然后被销毁
  – JVM 有时会移动剩余对象的一部分为了重建堆中大面积的空闲连续空间 问题
  如果 JVM 管理内存,您为什么需要关心?因为这并不意味着你不能有  内存泄漏 !
  大多数时候,您都在不知不觉中使用垃圾收集根。例如,假设您需要在程序的生命周期内存储一些对象(因为它们的初始化成本很高)。您可能会使用静态集合(List、Map 等)在代码中的任何位置存储和检索这些对象: public static Map myStoredObjects= new HashMap<>();
  但是,这样做可以防止 JVM 破坏集合中的对象。您可能会错误地遇到 OutOfMemoryError 。例如:  public class OOM {             public static List myCachedObjects = new ArrayList<>();             public static void main(String[] args) {                 for (int i = 0; i < 100_000_000; i++) {                     myCachedObjects.add(i);                 }             }         }
  输出是:
  线程"main"中的异常 java.lang.OutOfMemoryError:Java 堆空间
  Java 提供了不同类型的引用来避免 OutOfMemoryError。
  有些类型允许 JVM 释放对象,即使程序仍然需要它们。处理这些情况是开发人员的责任。 强引用
  强引用是标准引用。当您像这样在对象 obj 上创建时:
  MyClass obj = new MyClass ();
  您正在为新创建的 MyClass 实例创建一个名为"obj"的强引用。当垃圾收集器查找非活动对象时,它只检查对象是否是 强可达 的,这意味着通过强引用可传递地链接到垃圾收集根。
  使用这种类型的引用会强制 JVM 将对象保留在堆中,直到对象不被使用,如"垃圾收集器"部分所述。 软引用
  根据 java API soft reference 有:
  "软引用对象,由垃圾收集器根据内存需求自行清除"
  这意味着如果您在不同的 JVM(Oracle 的 Hotspot、Oracle 的 JRockit、IBM 的 J9 等)上运行您的程序,软引用的行为可能会发生变化。
  让我们看一下 Oracle 的 JVM Hotspot(标准和最常用的 JVM),看看它是如何管理软引用的。根据 Oracle 文档:
  "默认值为每兆字节 1000 毫秒,这意味着对于堆中每兆字节的可用空间,软引用将存活(在收集到对象的最后一个强引用之后)1 秒"
  这是一个具体的例子:假设堆是 512 MB,还有 400 MB 空闲。
  我们创建一个对象 A ,软引用到对象 缓存 ,并强引用 A 到对象 B 。由于 A 被强引用到 B ,它是强可达的并且不会被垃圾收集器删除(案例 1)。
  想象一下,现在 B  被删除了,所以 A 只是对 缓存 对象的软引用。如果对象 A 在接下来的 400 秒内没有被强引用,它将在超时后被删除(情况 2)。
  以下是如何操作软引用: public class ExampleSoftRef {     public static class A{       }     public static class B{         private A strongRef;           public void setStrongRef(A ref) {             this.strongRef = ref;         }     }     public static SoftReference cache;       public static void main(String[] args) throws InterruptedException{         //initialisation of the cache with a soft reference of instanceA         ExampleSoftRef.A instanceA = new ExampleSoftRef.A();         cache = new SoftReference(instanceA);         instanceA=null;         // instanceA  is now only soft reachable and can be deleted by the garbage collector after some time         Thread.sleep(5000);           ...         ExampleSoftRef.B instanceB = new ExampleSoftRef.B();         //since cache has a SoftReference of instance A, we can"t be sure that instanceA still exists         //we need to check and recreate an instanceA if needed         instanceA=cache.get();         if (instanceA ==null){             instanceA = new ExampleSoftRef.A();             cache = new SoftReference(instanceA);         }         instanceB.setStrongRef(instanceA);         instanceA=null;         // instanceA a is now only softly referenced by cache and strongly referenced by B so it cannot be cleared by the garbage collector           ...     } }
  但是即使软引用对象被垃圾收集器自动删除, 软引用 (也是对象)  也没有被删除!  所以,你仍然需要清除它们。例如,对于像 64 Mbytes (Xmx64m) 这样的小堆大小,尽管使用了软引用,但以下代码会给出 OutOfMemoryException。 public class TestSoftReference1 {       public static class MyBigObject{         //each instance has 128 bytes of data         int[] data = new int[128];     }     public static int CACHE_INITIAL_CAPACITY = 1_000_000;     public static Set> cache = new HashSet<>(CACHE_INITIAL_CAPACITY);       public static void main(String[] args) {         for (int i = 0; i < 1_000_000; i++) {             MyBigObject obj = new MyBigObject();             cache.add(new SoftReference<>(obj));             if (i%200_000 == 0){                 System.out.println("size of cache:" + cache.size());             }         }         System.out.println("End");     } }
  输出代码是:
  缓存大小:1
  缓存大小:200001
  缓存大小:400001
  缓存大小:600001
  线程"主"java.lang.OutOfMemoryError 中的异常:超出 GC 开销限制
  Oracle 提供了一个 ReferenceQueue ,当引用的对象只能软访问时,它会填充软引用。使用此队列,您可以清除软引用并避免 OutOfMemoryError。
  使用 ReferenceQueue,与上面相同的代码具有相同的堆大小(64 MB)但要存储更多数据(500 万对 100 万): public class TestSoftReference2 {     public static int removedSoftRefs = 0;       public static class MyBigObject {         //each instance has 128 bytes of data         int[] data = new int[128];     }       public static int CACHE_INITIAL_CAPACITY = 1_000_000;     public static Set> cache = new HashSet<>(             CACHE_INITIAL_CAPACITY);     public static ReferenceQueue unusedRefToDelete = new ReferenceQueue<>();       public static void main(String[] args) {         for (int i = 0; i < 5_000_000; i++) {             MyBigObject obj = new MyBigObject();             cache.add(new SoftReference<>(obj, unusedRefToDelete));             clearUselessReferences();         }         System.out.println("End, removed soft references=" + removedSoftRefs);     }       public static void clearUselessReferences() {         Reference<? extends MyBigObject> ref = unusedRefToDelete.poll();         while (ref != null) {             if (cache.remove(ref)) {                 removedSoftRefs++;             }             ref = unusedRefToDelete.poll();         }       } }
  输出是:
  结束,删除软引用=4976899
  当您需要存储许多对象时,软引用很有用,如果它们被 JVM 删除,这些对象可能会(代价高昂)重新实例化。 弱引用
  弱引用是一个比软引用更易变的概念。根据 JAVA API:
  "假设垃圾收集器在某个时间点确定一个对象是 弱可达的。届时,它将自动清除对该对象的所有弱引用以及对该对象可通过强引用链和软引用链访问的任何其他弱可达对象的所有弱引用。同时,它会声明所有以前的弱可达对象是可终结的。同时或在稍后的某个时间,它会将那些在引用队列中注册的新清除的弱引用排入队列。"
  这意味着当垃圾收集器检查所有对象时,如果它检测到一个对象只有对垃圾收集根的弱引用(即没有强引用或软引用链接到该对象),该对象将被标记为移除并尽快删除。使用 Wea kReference 的方法与使用 SoftReference 完全相同。因此,请看"软引用"部分的示例。
  Oracle 提供了一个非常有趣的基于弱引用的类:WeakHashMap。该映射具有弱引用键的特殊性。WeakHashMap 可以用作标准 Map。唯一的区别是它会 在键从堆中销毁后 自动清除: public class ExampleWeakHashMap {     public static Map cache = new WeakHashMap();       public static void main(String[] args) {         Integer i5 = new Integer(5);         cache.put(i5, "five");         i5=null;         //the entry {5,"five"} will stay in the Map until the next garbage collector call           Integer i2 = 2;         //the entry {2,"two"} will stay  in the Map until i2 is no more strongly referenced         cache.put(i2, "two");           //remebmber the OutOfMemoryError at the chapter "problem", this time it won"t happen         // because the Map will clear its entries.         for (int i = 6; i < 100_000_000; i++) {             cache.put(i,String.valueOf(i));         }     } }
  例如,我使用 Wea kHashMap 来解决以下问题:存储多个交易信息。我使用了这个结构:WeakHashMap> 其中 WeakHashMap 的键是一个包含交易 ID 的字符串,"简单"Map 是我需要在生命周期内保留的信息交易。有了这个结构,我肯定会在 WeakHashMap 中获取我的信息,因为包含事务 ID 的字符串在事务结束之前不会被销毁,而且我不必关心清理 Map。
  Oracle 建议使用 Wea kHashMap 作为"规范化"映射。 虚引用
  在垃圾收集过程中,没有对垃圾收集根的强/软引用的对象将被删除。在被删除之前,方法 finalize() 被调用。当一个对象被终结但没有被删除(还)时,它就变成了"幻影可达",这意味着在对象和垃圾收集根之间只有一个幻影引用。
  与软引用和弱引用不同,对对象使用显式幻像引用可以防止对象被删除。程序员需要显式或隐式地移除幻影引用,以便销毁最终化的对象。要显式清除幻影引用,程序员需要使用  ReferenceQueue  ,当对象完成时,它会填充幻影引用。
  幻影引用无法检索被引用的对象:幻影引用的 get() 方法始终返回 null,因此程序员无法再次使幻影可达对象强/软/弱可达。这是有道理的,因为幻影可达对象已经完成,所以如果重写的 finalize() 函数已清除资源,它可能不再工作。
  由于无法访问引用的对象,因此我看不出幻影引用有何用处。一个用例可能是,如果您需要在对象完成后执行操作,而您不能(或出于性能原因不想)在该对象的 finalize() 方法中执行特定操作。 结论
  我希望您现在对这些参考资料有了更好的了解。大多数时候,您不需要显式使用它们(也不应该)。但是,许多框架正在使用它们。如果你想了解东西是如何工作的,那么了解这个概念是很好的。

货殖列传年糕妈妈李丹阳带千万妈妈科学地偷懒澎湃新闻记者陆玫编者按史记货殖列传是最早专门记叙从事货殖(商业)活动的杰出人物的史书著作,司马迁阐释的经世济民的经济思想和商业智慧,被誉为历史思想及于经济,是书盖为创举。新一轮科技连签4人!湖人补强射手,接纳名宿之子,沙里夫圆梦,奥尼尔笑了连签4人!湖人补强射手,接纳名宿之子,沙里夫圆梦,奥尼尔笑了!北京时间6月24日,在今天的选秀大会上,湖人送出未来次轮签以及部分现金,从魔术得到第35顺位选秀权,从而选中来自密歇根中国队,金牌在24日晚间结束的2022年布达佩斯游泳世锦赛花样游泳集体自由自选决赛中,中国队发挥稳定,她们演绎的巾帼英雄拿到了96。7000的高分,再次获得冠军,这也是中国花样游泳队在本届世锦一部被大众错失的好剧宸汐缘,豆瓣评分高达8。4分,你看了吗此剧开播之前几乎零宣传,豆瓣评分从5。4分逆袭到8。4分,最初观众纷纷吐槽男主扮相老,女主颜值不高,可观看后却直呼真香!它,究竟是一部什么样的剧呢?喜欢追剧的小伙伴,一定不要错过。为韩国泡菜中文翻译问题,频频碰瓷中国的韩教授又找上谷歌来源环球网环球网报道见习记者付嘉骏从两年前开始频频在泡菜问题上碰瓷中国的那个韩国教授又跳出来了,这次他的目标是谷歌。据韩国纽西斯通讯社等多家韩国媒体23日报道,韩国诚信女子大学教授碳纤维行业深度报告长景气高成长赛道,国产替代创造绝佳投资窗口(报告出品方作者中信建投证券,杨光)一碳纤维材料性能优异,应用前景广阔1。1碳纤维规格多样,材料性能优异碳纤维材料性能优异,多规格产品可广泛应用于航空航天风电叶片等高附加值领域。碳罗永浩之后,清华教授批评苹果缺乏创新,不如乔布斯时代关于苹果缺乏创新已经成为全网共识,几乎每隔一段时间都会有人出来批判,但苹果却从来不思进取。最新有媒体报道,清华大学教授痛批苹果缺乏创新,现在无法跟乔布斯时代相比,只能通过夸大商业收事以密成!高手表面人畜无害,实则鹰视狼顾你知道为什么你到今天还是很穷,因为你总活在非黑即白的世界里。就像小孩看电视,非要分出好人和坏蛋。真正的高手,都活在灰色地带。记得以前我和我的老板出差拜访客户,路上经过一片郊区,是一来路不易分外珍惜!中国花游要继续奋进向前北京时间6月24日晚,在第19届国际泳联游泳世锦赛花样游泳集体自由自选决赛中,8位中国姑娘凭借成套动作巾帼英雄,最终以96。7000分获得了冠军。这也是中国国家花样游泳队在本届世锦武侠世界同样有人情世故,你能做好其中周旋吗?武侠可以说是每一个人年少时候都曾经幻想过的东西,如果能够在那一个光怪陆离的武侠世界里面,加入哪一个门派修炼几部武林秘籍,那么我们应该也能够成为那样一个能够飞檐走壁,除恶扬善的大侠吧大量商铺关门,可满大街越来越多药店与餐饮店,又一社会怪象要是在社会上大家有点资金,会不会选择创业呢?又会选择什么方向的创业项目呢?相信大多数人都会选择租个门面做生意吧!但是不知道大家有没有放下吧,这两年随着国内社会逐渐恢复常态化的发展状
扒一扒撞脸明星的素人,贾玲梨涡都一样,王宝强像戴了假发在写这篇文章之前,我也怀疑,真的有人完全没有血缘能撞脸成一模一样吗?事实证明,还真有!以下这几位素人撞脸明星一个比一个像,简直像复刻的一样。01撞脸贾玲马超是呼和浩特的一名消防员。哪位明星能满足你对恋人的所有幻想?倪妮罕见换风格更美了现如今娱乐圈里女明星的身材管理,可以说是非常严格,圈粉无数的同时,也成了国民女友,非常具有代表性的就是下面几位徐冬冬徐冬冬应该是完美恋人的典型人物了,在电视剧余罪中,大家看得到男主罗志祥复出了,并称失去的要全部拿回来?罗志祥要复出了?今天在网上看到杭州日报视频号发布的这样的一段视频,还是蛮吃惊的,难道罗志祥又回到内地娱乐圈来了?再仔细一看,原来是在台湾省台北市举行的演唱会,而并非内地。曾经的时间字画拍卖app开发需要具备哪些功能?传统的艺术品交易模式一般是由传统画廊拍卖公司来完成交易。现在构建一个由线上终端自由买卖大数据系统管理及处理的新型交易模式,整个交易过程中也将更透明更公正。字画拍卖app开发,互联网比特币BTC持有者应该知道底部是一位智者曾经说过,要知道你的未来,你必须知道你的过去。在确定比特币BTC是否最终在持续的熊市中触底时,链上分析平台Glassnode在一份新报告中分析并比较了过去熊市周期的特征和持秦力洪只要蔚来在,换电就会一直干下去电动势不管对蔚来品牌有何看法,但都无可否认,在高端纯电市场,蔚来是当之无愧的引领者,也是中国高端品牌的破局者。蔚来何以达成这样的非凡成就?答案是换电。尽管换电已经有上百年历史(宁德时代开直播预告王岑连线星愿宇宙详解数字藏品实体经济直播时间7月15日晚上1030主题数字藏品赋能实体经济当前,Web3。0已然是大势所趋,星愿宇宙平台以自身携带的航天科技属性为基础,将中国特色Web3。0的新技术赋能数字藏品解决方注意!这15款App不要下载国家计算机病毒应急处理中心近期通过互联网监测发现15款移动App存在隐私不合规行为违反网络安全法个人信息保护法相关规定涉嫌超范围采集个人隐私信息1在App首次运行时未通过弹窗等明显164页,2022新版Java面试手册免费领取小伙伴们,2022新版Java面试手册来啦,这本小册子总计164页,全都是面试中的高频题目,有兴趣的小伙伴们不妨来看一下,为金九银十冲刺上岸做一下准备。获取完整PDF内容请转发点赞新能源品牌造车,多数被困在系统里面了汽车智能化的发展比起手机的智能化,其实有很大的局限性,因为有很大的壁垒还没有走出自动驾驶的技术瓶颈,再加上汽车行业拥有百年的复杂工艺,想要瞬间超越似乎不可能。不过,各车企也是奋力在戴思乐带您了解新型智慧运动场馆解决方案随着健康运动的不断发展,体育智能化的需要在不断地提升,为了让运动场馆及管理上越来越方便快捷,许多运动场馆采用的是智慧体育场馆运营系统,打造出以数字体育场馆运营管理智能物联平台运动大