小工具知识网

当前位置: 首页 > 行业知识 > JAVA 内存泄漏相关知识学习

行业知识

JAVA 内存泄漏相关知识学习

2026-11-11 06:38:43 来源:互联网转载

1 强引用

强引���回收机制

强引用需要切断引用关系,才可以让对象被垃圾回收器正常回收

示例:

 @Test    fun testMemoryLeak(){        var m:M? = M()        System.gc()        println("打印m对象 == $m")        m = null        System.gc()        println("置空之后打印m == $m")    }

结果:

打印m对象 == com.example.testdemo2.M@6f53b8a

置空之后打印m == null

该对象被回收了finalize

2 弱引用

弱引用的回收机制

弱引用只要java触发gc垃圾回收,被弱引用持有的对象就会被回收掉。

示例:

 @Test    fun testWeakReference(){        val ref = WeakReference(Person())        println("打印弱引用持有的对象 == ${ref.get()}")        Thread.sleep(5000)        println("打印弱引用持有的对象 == ${ref.get()}")        Thread.sleep(5000)        System.gc()        println("GC之后打印弱引用持有的对象 == ${ref.get()}")    }    class Person{        var name = "zhangsan"    }

结果:

打印弱引用持有的对象 == com.example.testdemo2.ExampleUnitTest$Person@6b695b06

打印弱引用持有的对象 == com.example.testdemo2.ExampleUnitTest$Person@6b695b06

GC之后打印弱引用持有的对象 == null

3 软引用

软引用回收机制

软引用会在jvm分配内存不足的时候,释放回收其引用的对象,在触发gc时,只要内存分配足够,是不会被回收的,只有到使用内存大于分配内存的时候才会回收该对象的引用。

示例

 @Test    fun testSoftReference() {        val softRef = SoftReference(ByteArray(1024 * 1024 * 10))        println("打印软引用 == ${softRef.get()}")        System.gc()        Thread.sleep(500)        println("打印软引用 == ${softRef.get()}")        val softRef2 = SoftReference(ByteArray(1024 * 1024 * 12))        println("打印软引用 == ${softRef.get()}")    }

结果:

jvm分配空间为20M的情况下,就会造成软引用中的对象被回收掉

打印软引用 == [B@58a9760d

打印软引用 == [B@58a9760d

打印软引用 == null

4 ThreadLocal的使用

ThreadLocal 自带线程隔离机制,因为ThreadLocal在设置对象的时候,会用当前的线程作为key存储当前设置的引用对象,所以每个线程中只能获取到自己存放的引用对象,无法获取其他线程中存储的值,从而起到的线程隔离的作用。

示例

 @Test    fun testThreadLocal(){        val threadLocal = ThreadLocal()        Thread{            threadLocal.set(Person())            println("线程1 == 打印threadLocal中的存储的信息 == ${threadLocal.get()}")            threadLocal.remove()            println("线程11 == 打印threadLocal中的存储的信息 == ${threadLocal.get()}")        }.start()        Thread{            println("线程2 == 打印threadLocal中的存储的信息 == ${threadLocal.get()}")        }.start()    }    class Person{        var name = "zhangsan"    }

结果

线程2 == 打印threadLocal中的存储的信息 == null

线程1 == 打印threadLocal中的存储的信息 == com.benben.TestDataDemo.TestDataDemoApplicationTests$Person@6388e817

线程11 == 打印threadLocal中的存储的信息 == null

从结果上看 只有线程1的日志中正常拿到了设置进去的Person对象,线程11之所以没有拿到 是因为当前线程中的threadLocal对象已经将存储的信息进行了remove,线程2拿不到的原因是因为不在同一个线程中,即使使用同一个threadLocal对象也无法获取相同的map容器,所以获取存储对象的时候拿到了null

上一篇:vue项目使用js监听浏览器关闭、刷新、后退事件

下一篇:迅雷高效下载PDF图片攻略