首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

当我在Thread对象上调用run()时,为什么我的Java程序会泄漏内存?

当你在一个Thread对象上调用run()方法时,实际上创建了一个Runnable实例,而不是一个线程。而run()方法是一个静态方法,所以你不能直接调用一个类的run()方法,而应该在线程外部实例化Thread的实例。所以,当你调用run()方法时,是在调用Thread实例的run()方法,而不是在创建新线程。

当你在Thread对象上调用run()时,你的Java程序并不会泄漏内存。但是,如果你在run()方法中使用了一些可能导致内存泄漏的方法或代码,那么这段代码可能导致程序的内存泄漏。

为了避免内存泄漏,你应该在使用完线程后,显式地调用Thread#interrupt()方法以取消线程的执行。此外,如果线程在长时间运行时可能需要消耗大量的系统资源,可以考虑使用线程池,这样可以让线程复用在有限的线程中,避免重复创建线程导致的资源浪费。最后,还要注意避免在run()方法中使用可能占用大量内存的方法,否则可能会导致Java程序的内存泄漏。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

为什么 ThreadLocal 可以做到线程隔离?

这个特性并发编程中非常有用,能够避免多线程之间数据竞争问题,提高程序可靠性和性能。那么,为什么 ThreadLocal 可以做到线程隔离呢?以下是一个详细分析。...set() 方法 当我调用 threadLocal.set() 方法来保存数据,内部也是先获取对应 ThreadLocalMap 对象,然后根据 ThreadLocal 实例作为 key,将对应值保存到...remove() 方法 当我调用 threadLocal.remove() 方法来删除保存数据,它内部也是根据当前线程获取对应 ThreadLocalMap 对象,然后根据 ThreadLocal...注意事项 当然,ThreadLocal 也有一些注意事项: (1)使用 ThreadLocal ,必须考虑内存泄漏问题。...当我们使用 ThreadLocal ,需要注意内存泄漏和数据初始化问题,以充分发挥它优势。

12810

(十五)ThreadLocal用法,如何解决内存泄漏

而强引用是造成Java内存泄漏主要原因之一,内存空间不足Java虚拟机会抛出OutOfMemoryError ,使程序异常终止,但是注意,抛出错误也不会回收这些强引用对象。...ThreadLocal有通过方法:调用get,set或remove方法,就会尝试删除key为nullentry,可以释放value对象所占用内存。...而强引用是造成Java内存泄漏主要原因之一,内存空间不足Java虚拟机会抛出OutOfMemoryError ,使程序异常终止,但是注意,抛出错误也不会回收这些强引用对象。...ThreadLocal有通过方法:调用get,set或remove方法,就会尝试删除key为nullentry,可以释放value对象所占用内存。...而强引用是造成Java内存泄漏主要原因之一,内存空间不足Java虚拟机会抛出OutOfMemoryError ,使程序异常终止,但是注意,抛出错误也不会回收这些强引用对象

1.2K20

Android 内存泄漏分析心得

Java内存分配 静态储存区:编译就分配好,程序整个运行期间都存在。...它们缓冲不仅存在于 java虚拟机内,还存在于java虚拟机外。如果我们仅仅是把它引用设置为null,而不关闭它们,往往造成内存泄漏。...因此对于资源性对象不使用时候,应该调用close()函数,将其关闭掉,然后才置为null. 我们程序退出一定要确保我们资源性对象已经关闭。...集合中对象没清理造成内存泄漏 我们通常把一些对象引用加入到了集合容器(比如ArrayList)中,当我们不需要该对象,并没有把它引用从集合中清理掉,这样这个集合就会越来越大。...WebView造成泄露 当我们不要使用WebView对象,应该调用destory()函数来销毁它,并释放其占用内存,否则其占用内存长期也不能被回收,从而造成内存泄露。

2.3K10

头条面试官手把手教学 ThreadLocal

关于JavaJVM跟并发时候看你水那个JVM系列还有并发系列都过了。最后还问了点ThreadLocal问题。 SoWhat:擦,ThreadLocal有啥好问就是个底层Map啊!...如果我们没有删除Entry并且CurrentThread依然运行情况下,强引用链如下图红色,导致Entry内存泄漏。 ? 在这里插入图片描述 结论: 强引用无法避免内存泄漏。...第一点表明当我使用完毕ThreadLocal后,调用其对应remove方法删除对应Entry就可以避免内存泄漏。...为什么用弱引用 前面分析后知道内存泄漏跟强弱引用无关,那么为什么还要用弱引用?我们知道避免内存泄漏方式有两个。 ThreadLocal使用完毕后调用remove方法删除对应Entry。...事实ThreadLocalMap中set/getEntry方法中,我们会对key = null (也就是ThreadLocal为null)进行判定,如果key = null,则系统认为value没用了也设置为

38710

看完这篇文章,解决 APP 中 90 % 内存异常问题

为什么 Java 都给我们提供了垃圾回收机制,程序有时还会导致内存泄漏内存溢出 OOM,甚至导致程序 Crash 。接下来我们就对实际开发中出现这些内存问题,来进行优化。...(本次需要优化地方) 虚拟机能管理最大一块内存 GC 主战场 会出现 OOM 对象实例 数据内容 JAVA GC 如何确定内存回收 随着程序运行,内存实例对象、变量等占据内存越来越多,...不能满足被回收条件,尽管调用 System.gc() 也还是不能得到回收, 这就造成了 内存泄漏 。当然,现在虚拟机基本都不采用此方式。 可达性分析算法 ?...注意: 软引用对象 jvm 内存不够时候才会被回收,我们调用 System.gc() 方法只是起通知作用, JVM 什么时候扫描回收对象是 JVM 自己状态决定。...枚举优化 缺点: 每一个枚举值都是一个单例对象,使用它时会增加额外内存消耗,所以枚举相比与 Integer 和 String 会占用更多内存 较多使用 Enum 增加 DEX 文件大小,造成运行时更多

72530

手把手教你定位常见Java性能问题

mat内存工具 MAT(Memory Analyzer Tool)工具是eclipse一个插件(MAT也可以单独使用),它分析大内存dump文件,可以非常直观看到各个对象堆空间中所占用内存大小...内存泄露 模拟内存泄漏借助了ThreadLocal对象来完成,ThreadLocal是一个线程私有变量,可以绑定到线程整个线程生命周期都会存在,但是由于ThreadLocal特殊性,ThreadLocal...是不是只要加大内存就行了呢?如果是普通内存溢出也许扩大内存就行了,但是如果是内存泄漏的话,扩大内存不一就会被占满,所以我们还需要确定是不是内存泄漏。...线程频繁切换 上下文切换导致将大量CPU时间浪费寄存器、内核栈以及虚拟内存保存和恢复,导致系统整体性能下降。当你发现系统性能出现明显下降时候,需要考虑是否发生了大量线程上下文切换。...发生硬件中断,CPU 进程会被中断挂起,转而执行内核中中断服务程序

1.1K10

(2021最新版)Java后端面试题|Java多线程与并发

(2)等待池 当我调用wait()方法后,线程放到等待池当中,等待池线程是不会去竞争同步锁。...不是线程安全、应该是内存安全,堆是共享内存,可以被所有线程访问 当多个线程访问一个对象,如果不用进行额外同步控制或其他协调操作,调用这个对象行为都可以获得正确结果,我们就说这个对象是线程安全...Java中,堆是Java虚拟机所管理内存中最大一块,是所有线程共享一块内存区域,虚拟机启动创建。堆所存在内存区域唯一目的就是存放对象实例,几乎所有的对象实例以及数组都在这里分配内存。...举例, GC垃圾回收线程:就是一个经典守护线程,当我程序中不再有任何运行Thread程序就不会再产生垃圾,垃圾回收器也就无事可做,所以当垃圾回收线程是JVM仅剩线程,垃圾回收线程自动离开...因此,ThreadLocal内存泄漏根源是:由于ThreadLocalMap生命周期跟Thread一样长,如果没有手动删除对应key就会导致内存泄漏,而不是因为弱引用。

57600

两万字!多线程硬核50问!

我们先来一起回忆下java内存模型(jmm): Java虚拟机规范试图定义一种Java内存模型,来屏蔽掉各种硬件和操作系统内存访问差异,以实现让Java程序各种平台上都能达到一致内存访问效果。...大家可以看下之前这篇文章哈: ThreadLocal八个关键知识点 17. TreadLocal为什么导致内存泄漏呢? 弱引用导致内存泄漏呢?...key是弱引用,GC回收影响ThreadLocal正常工作嘛? ThreadLocal内存泄漏demo 17.1 弱引用导致内存泄漏呢?...实际,我们内存泄漏根本原因是,不再被使用Entry,没有从线程ThreadLocalMap中删除。...过多线程,还会导致内存泄漏,笔者以前公司,看到一个生产问题:一个第三方包是使用new Thread来实现,使用完没有恰当回收销毁,最后引发内存泄漏问题。

39110

面试官还问Handler?那我要给你讲个故事

java.lang.Thread.run(Thread.java:919) 通过报错提示 “not called Looper.prepare()” 可以看出提示没有调用Looper.prepare(...只需new Handler()之前调用下Looper.prepare()即可。 2. 为什么主线程可以直接new Handler? 子线程直接new Handler会报错,主线程为什么就不会报错呢?...首先普及下什么叫内存泄露,当一个对象不再使用本该被回收,但另外一个正在使用对象持有它引用从而导致它不能被回收,这导致本该被回收对象不能被回收而停留在堆内存中,这种情况下就产生了内存泄漏。...其实我们写非静态内部类和非静态匿名内部类,在编译器编译过程中,隐式帮我们传入了this这个参数,这也是为什么,我们平时方法中能使用this这个关键字原因,了解了隐式引用,那么为什么它会是导致内存泄漏...这里又得说明一下,虚拟机垃圾回收策略。 垃圾回收机制:Java采用根搜索算法,当GC Roots不可达,并且对象finalize没有自救情况下,才会回收。

40660

彻底攻克ThreadLocal:搞懂原理、实战应用,深挖源码!扩展InheritableThreadLocal、FastThreadLocal!

当线程调用 ThreadLocal set 方法,它实际自己 threadLocals 映射中设置值;当调用 get 方法,它是从自己 threadLocals 映射中检索值。...synchronized适用于多个线程需要共享和协作访问同一资源情况。 面试题5:ThreadLocal为什么导致内存泄漏?...为了避免这种内存泄漏,最佳实践是不再需要ThreadLocal变量显式调用其remove()方法。...使用线程池尤其重要,因为线程可能会被重用,而它们ThreadLocalMap也随之保留。 面试题6:为什么ThreadLocalkey要用弱引用?...答案: ThreadLocalkey使用弱引用主要目的是为了帮助避免内存泄漏Java中,弱引用(WeakReference)是一种引用类型,它不会阻止其引用对象被垃圾收集器回收。

82201

JVM故障分析及性能优化实战(II)——jstack生成Thread Dump日志结构解析

这一部分详细含义见 Java内存泄漏分析系列之四:jstack生成Thread Dump日志线程状态分析。...JBoss启动之后,也唤起DestroyJavaVM线程,处于等待状态,等待其它线程(java线程和native线程)退出通知它卸载JVM。...: RUNNABLE "Finalizer" 这个线程也是main线程之后创建,其优先级为10,主要用于垃圾收集前,调用对象finalize()方法;关于Finalizer线程几点: (1)只有当开始一轮垃圾收集...这对于防止因为应用代码中直接使用native库或者第三方一些监控工具内存泄漏有非常大帮助。...第五部分:JNI global references count 这一部分主要回收那些native代码被引用,但在java代码中却没有存活必要引用,对于防止因为应用代码中直接使用native库或第三方一些监控工具内存泄漏有非常大帮助

2.1K40

ThreadLocal 原理及问题,一网打尽!

你好,是田哥 ThreadLocal 是一个线程内部数据存储类,通过它可以指定线程中存储数据,数据存储以后,只有指定线程中可以获取到存储数据,对于其他线程来说无法获取到数据。...当我们启用了 ThreadLocal 以后: 内存占用最高升至 150M,一般情况下稳定在 90M 左右,那么加入一个 ThreadLocal 后,内存占用真的这么多?...只有 remove() 方法中显式调用了 expungeStaleEntry 方法。 从表面上看内存泄漏根源在于使用了弱引用,但是另一个问题也同样值得 思考:为什么使用弱引用而不是强引用?...对象实例不会被回收,导致 Entry 内存泄漏。...这也就是为什么上面的程序为什么输出一样结果: 5 个线程中保存是同一 Number 对象引用,在线程睡眠时候, 其他线程将 num 变量进行了修改,而修改对象 Number 实例是同一份,

17410

ThreadLocal之美!

起点是get方法,map为空,调用initial方法罢了 内存泄漏 很多人都不容为什么拦截器最后,要remove一下,Jvm垃圾回收器不是可以回收吗?...这里先理清一下内存泄漏内存溢出区别 内存泄漏指的是:对象不使用了,应该被回收,但是没被回收 内存溢出指的是:就是申请内存不够用,造成outofMemory 再讲一下:四大引用 强软弱虚 强引用,Reference...,目的是让系统知道这个对象被回收 总结 引用类型 被垃圾回收时刻 用途 生存时间 强引用 从来不会 对象一般状态 JVM停止运行时终止 软引用 在内存不足 对象简单,缓存,文件缓存,图片缓存 内存不足终止...,这样也是可以回收 但是当我们用线程池时候,一个线程是重复利用,比如拦截器这里,这个线程处理完一个用户,再处理下一个,那么这里threadLocal和value是很多,value强引用,是不会被回收...我们知道,initialValue方法,即使不调用,也是会有一个默认null,,顶多get到一个null,那么为什么有人遇到get下,报空指针异常问题呢?

20320

Java多线程面试问答

例如,Servlet性能上比CGI更好,因为Servlet支持多线程,但CGI不支持。 3、用户线程和守护线程之间有什么区别? 当我Java程序中创建线程,它被称为用户线程。...当我Java程序中创建线程,其状态为“new”。然后,我们启动将其状态更改为Runnable线程。线程调度程序负责将CPU分配给可运行线程池中线程,使其状态更改为running(运行中)。...当线程在任何对象调用wait(),它必须在要离开对象具有监视器,并进入等待状态,直到对该对象任何其他线程调用notify()为止。...同样,当线程在任何对象调用notify(),它将监视器留在对象,而其他等待线程可以在对象获取监视器。...这就是为什么将这些方法设为静态原因,以便当该方法被静态调用时,它可以在当前执行线程运行,并且避免使可能认为可以某些非运行线程上调用这些方法程序员感到困惑。

1.1K40

Handler源码和9个常见问题解答,这些你都掌握了吗?

系统为什么不建议子线程中访问UI? 这是因为 Android UI控件不是线程安全,如果在多线程中并发访问可能导致UI控件处于不可预期状态,那么为什么系统不对UI控件访问加上锁机制呢?...对象只是被调用了它run方法,根本并没有启动一个线程,源码如下: //Handler.java public final boolean post(@NonNull Runnable r) {...如何处理Handler使用不当造成内存泄漏?...有延时消息,界面关闭后及时移除Message/Runnable,调用handler.removeCallbacksAndMessages(null) 内部类导致内存泄漏改为静态内部类,并对上下文或者...具体内存泄漏分析和解决可以参考这篇文章。同时还有一个很关键点,如果有个延时消息,当界面关闭,该Handler中消息还没有处理完毕,那么最终这个消息是怎么处理

1.2K00

ThreadLocal与Java引用类型(文末含福利)

0 写在前边 今天以 “TheadLocal 为什么导致内存泄漏” 为题与朋友们讨论了一波,引出了一些原理性内容,本文就这个问题作答,并扩展相关知识点 1 ThreadLocal 和 ThreadLocalMap...导致内存泄漏原因在于程序员未在使用完ThreadLocalMap中存储对象后清除这些对象。...当局部 value 对象所在方法结束,栈桢被清空,会将局部 value 对象引用销毁,垃圾收集器清除没有引用对象。...7 线程池累积 ThreadLocalMap 占用内存而出现内存泄漏吗?...9 【扩展】Java对象引用类型 强引用:常见new对象,只要还有强引用对象,则不会被GC 软引用:比强引用弱,仅当JVM内存不足才会清理,清理时机OOM前 弱引用:只提供非强制映射关系,GC

56010

使用ThreadLocal怕内存泄漏?那你应该来看看这篇文章

我们来看看维基百科解释: ❝计算机程序设计中,「弱引用」与强引用相对,是指不能确保其引用对象不会被垃圾回收器回收引用。...❞ 进行垃圾回收,回收器回收掉这些弱引用。...如果「Entry」key使用强引用,key引用一直指向ThreadLocal对象,如果线程Thread存在,Entry也一直存在,会有内存泄漏危险。 但是即使使用弱引用还是会有内存泄漏风险。...ThreadLocal被回收,key值变为null,导致整个value再也无法被访问。虽然依然存在内存泄漏,但比强引用多了一层保障。 解决内存泄漏问题 那我们如何解决内存泄漏问题呢?...从而避免内存泄漏。所以在用完ThreadLocal,注意调用一下remove方法即可。

27420
领券