Java提供了四个级别的参考:强引用,软引用,弱参考和虚拟使用。除强引用外,其他参考类型均在java.lang.ref软件包中实现,它们都来自java.lang.ref.Reference,如图所示:
您可以看到,除了弱点和土著用途外,参考还具有派生的类最终确定器,用于实现我们经常调用的最终函数。
在引入参考类型之前,让我们介绍与所有参考类型有关的内容:引用Queue Java.lang.refrencequeue。
参考等级可以与软引用,弱参考和诱导结合使用。注重参考标题,我们只需要知道最重要的一点:参考等级中存在的对象并非由JVM回收,并且它是在回收的道路上。。
那么Rerferencequeue可以做什么?既然我们知道最重要的一点,当JVM回收对象时,相当于发出通知,告诉我们XX已被回收,那么我们可以解释回收物体的后果。Coursethis的动作也可以在最终确定()中完成,但是最好不要这样做!交叉路口
顺便说一句,最终确定的实现:将要回收并包含finalize()函数的每个对象将在正式回收之前将其添加到称为最终的througeThread线程的执行队列中。该队列是我们的参考标题,其中队列中的对象是最终的。从上面的UML类图来看,可以看出最终器是从最终重新获得的。每个最终器都用要回收的对象包装。然后,队列中的元素将执行最终确定函数,因此可能会有一个不良的最终化函数。将最终器引用的对象长时间引用,并且无法释放。很长一段时间以来,可能会导致OOM长时间积聚并进一步增加GC压力
强引用是程序中普遍使用的参考类型。强引用的对象具有矮人的特征,并且不会被回收。例如:
在上面的代码中,STR是对StringBuffer实例的有力引用。其中,STR的局部变量分配在堆栈上,并且StringBuffer实例分配在堆上(当然可以在堆栈上分配)。如果目前执行代码:
然后,StringBuffer对象实例有两个引用。因此,如何使对象实例不再具有很强的引用?实际上没有引用指向此实例:
强引号具有以下特征:1)对于强引用,您可以直接访问目标对象2)对于强引用对象,指向系统的对象将不会随时回收。即使OOM 3)基于第二点,因此强有力的参考可能会导致内存泄漏
软引用实现为java.lang.ref.softreference。与强有力的参考资料相比,它略有弱。如果堆叠的内存空间不足,则可以回收软参考对象。软引用通常可用于缓存函数。软件参考也可以与ReferenceQueue结合使用。如果已回收软参考点的对象实例,则JVM将将此软引用添加到与之关联的参考标题中。
使用JVM参数-XMS7M -XMX7M -XX:+PRINTGC运行以下代码:
运行后的结果:
在示例程序中,堆的大小为7m,并且在发生GC时打开printGC参数以打印GC日志。接下来的两个部分分为两部分:
第1部分:首先,在主程序中构建一个新的用户对象,在用户对象中保存4M大小的字节数组,并且暂时认为该对象的大小为4M(当然必须大于4m),然后建立软引用的新用户,将对用户对象实例进行强引用。这次,在手动通过system.gc()手动反应垃圾回收后,可以是看到仍然可以获得用户对象的内容,表明尽管垃圾回收发生了,但实际上,现在的内存就足够了,并且将无法恢复软参考。第2部分:然后,第一部分,并且然后尝试再次分配4m大小的字节阵列。由于我们的桩尺寸仅为7m,因此在此时不得分配。大约4m的空间(即我们的软参考对象),以便可以容纳新分布的4m字节阵列。之后,软参考对象获得null。
结论:当系统发生系统时,系统发生时可能不会回收软参考对象。除非内存资源紧密且不足,否则将回收软参考对象,因此软参考对象不会导致内存泄漏。
应用程序方案:缓存
弱参考比软引用略有弱。当系统发生时,无论系统资源目前是否足够,弱参考都将被回收。当然,垃圾回收线的优先级相对较低,并且可能无法及时找到弱参考。。如果弱参考点的对象实例被回收,则JVM将将此弱参考添加到与之关联的参考标题中。
使用JVM参数-XMS10M -XMX10M -XX:+PRINTGC运行以下代码:
获取以下输入:
从输出可以看出,在手动强迫GC后,显然有4M空间的回收利用,并且获得的用户为无效,表明在此GC中,我们的弱参考对象是回收的。
阅读了软参考和弱参考后,您可以看到这两个参考更适合那些可支配的缓存。当系统内存资源不足时,这些缓存数据将被回收以提供更多的内存空间。足够的这些缓存数据可以长期存在。
应用程序方案:1)ThreadLocal解决内存泄漏
让我们看一下threadlocal源代码中的弱参考:threadlocal.threadlocalmap
每个线程都会有一个螺纹。threadLocalMap,threadlocalmap底层实际上是一个输入阵列。注意此条目继承了fealReference,而弱参考的类型是我们的输入键,即ThreadLocal cocal对象。首先,我们如何设计条目?
我们会以这种方式设计并可以实现线程排除的目的,但是问题是什么?让我们再考虑一下:1。我们在代码中使用螺纹插座来实现线程独家数据
2.执行test1的线程持有螺纹。threadLocalMap 3,threadlocal.threadlocalmap保留条目4,条目保留threadLocal and value 5,test1也由JVM使用,这意味着我们将不再使用此thread.Exclusive数据。
以上是强大的参考类型,创建后某些线程不会被破坏。它可能伴随着我们的系统,并在同月的同一个月死亡,这意味着可能存在一些线程和保存的价值。强烈参考的存在逐渐破坏了我们的内存并导致内存溢出。
下一点是为什么当弱参考恢复弱参考时资源是否足够恢复。有人可能会问。存在,仍然有记忆泄漏!
是的,只要使用螺纹插座,就必须建议使用或检查是否有螺纹插座的位置可以显示删除方法以显示该条目的删除。
因此,有人可能会再次问,因为我们需要显示删除?您要设计什么?
我个人认为,这是对内存泄漏的一种解决方案,因为总会有粗心的程序员忘记删除,或者永远不会被称为这些未使用的对象,当获取,设置和删除ThreadLocal时,他们发现,搜索哈希时的密钥是无效的,这意味着此条目无效。目前,ThreadLocal可以保证我们将帮助我们接受此条目。
2)弱hashmap实际上与theadlocal相同。
3)它也可以用于冷漠
虚拟性的使用是四种类型的参考类型中最弱的。如果仅使用对象实例,则与无参考的实例相同。软引用和弱参考是相似的,但是与其他参考相比,其他参考之间的差异略大:
1)通话方法的使用始终是无效的,也就是说,不足的目标对象始终无法到达。直接查看源代码:
2)虚拟性中只有一种构造方法。
应用程序方案:专用内存回收
窃窃私语:此外,我不知道该虚拟用途可以使用哪些场景。