Java 多线程 - 为什么创建一个线程就开销大了?和创建一个普通 Java 对象有什么差别?
频繁创建新线程有什么缺点?
1.不受控风险
系统资源有限,每个人针对不同业务都可以手动创建线程,并且创建标准不一样(比如线程没有名字)。当系统运行起来,所有线程都在疯狂抢占资源,无组织无纪律,内存很容易被无情榨干耗尽。
另外,过多的线程自然也会引起上下文切换的开销。
2.频繁创建开销大
new Thread() 在操作系统层面并没有创建新的线程;
真正转换为操作系统层面创建一个线程,还要调用操作系统内核的API,然后操作系统要为该线程分配一系列的资源。
2.1 new Object() 过程
Object obj = new Object();
当我需要【对象】时,我就会给自己 new 一个(不知你是否和我一样),这个过程你应该很熟悉了:
- 分配一块内存 M
- 在内存 M 上初始化该对象
- 将内存 M 的地址赋值给引用变量 obj
就是这么简单
2.2 new Thread() 过程
上面已经提到了,创建一个线程还要调用操作系统内核API。为了更好的理解创建并启动一个线程的开销,我们需要看看 JVM 在背后帮我们做了哪些事情:
- 它为一个线程栈分配内存,该栈为每个线程方法调用保存一个栈帧
- 每一栈帧由一个局部变量数组、返回值、操作数堆栈和常量池组成
- 一些支持本机方法的 jvm 也会分配一个本机堆栈
- 每个线程获得一个程序计数器,告诉它当前处理器执行的指令是什么
- 系统创建一个与Java线程对应的本机线程
- 将与线程相关的描述符添加到JVM内部数据结构中
- 线程共享堆和方法区域
这段描述稍稍有点抽象,用数据来说明创建一个线程(即便不干什么)需要多大空间呢?答案是大约 1M
左右
java -XX:+UnlockDiagnosticVMOptions -XX:NativeMemoryTracking=summary -XX:+PrintNMTStatistics -version
上图是我用 Java8 的测试结果,19个线程,预留和提交的大概都是19000+KB,平均每个线程大概需要 1M 左右的大小(Java11的结果完全不同,这个大家自行测试吧)
相信到这里你已经明白了,对于性能要求严苛的现在,频繁手动创建/销毁线程的代价是非常巨大的,解决方案自然也是你知道的线程池了
参考文献
作者:日拱一兵链接:https://juejin.cn/post/6844904134324256775
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
posted on 2021-09-13 13:43 frank_cui 阅读(1511) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
2020-09-13 多线程 - 如何合理配置线程池