Java程序员在编码过程中通常不需要考虑内存问题
来源:互联网 发布:西安软件退税政策 编辑:程序博客网 时间:2024/05/21 11:26
Java程序员在编码过程中通常不需要考虑内存问题,JVM经过高度优化的GC机制大部分情况下都能够很好地处理堆(Heap)的清理问题。以至于许多Java程序员认为,我只需要关心何时创建对象,而回收对象,就交给GC来做吧!甚至有人说,如果在编程过程中频繁考虑内存问题,是一种退化,这些事情应该交给编译器,交给虚拟机来解决。
这话其实也没有太大问题,的确,大部分场景下关心内存、GC的问题,显得有点“杞人忧天”了,高老爷说过:
过早优化是万恶之源。
但另一方面,什么才是“过早优化”?
If we could do things right for the first time, why not?
事实上JVM的内存模型( JMM )理应是Java程序员的基础知识,处理过几次JVM线上内存问题之后就会很明显感受到,很多系统问题,都是内存问题。
对JVM内存结构感兴趣的同学可以看下 浅析Java虚拟机结构与机制 这篇文章,本文就不再赘述了,本文也并不关注具体的GC算法,相关的文章汗牛充栋,随时可查。
另外,不要指望GC优化的这些技巧,可以对应用性能有成倍的提高,特别是对I/O密集型的应用,或是实际落在YoungGC上的优化,可能效果只是帮你减少那么一点YoungGC的频率。
但我认为,优秀程序员的价值,不在于其所掌握的几招屠龙之术,而是在细节中见真著,就像前面说的,如果我们可以一次把事情做对,并且做好,在允许的范围内尽可能追求卓越,为什么不去做呢?
一、GC分代的基本假设
大部分GC算法,都将堆内存做分代(Generation)处理,但是为什么要分代呢,又为什么不叫内存分区、分段,而要用面向时间、年龄的“代”来表示不同的内存区域?
GC分代的基本假设是:
绝大部分对象的生命周期都非常短暂,存活时间短。
而这些短命的对象,恰恰是GC算法需要首先关注的。所以在大部分的GC中,YoungGC(也称作MinorGC)占了绝大部分,对于负载不高的应用,可能跑了数个月都不会发生FullGC。
基于这个前提,在编码过程中,我们应该尽可能地缩短对象的生命周期。在过去,分配对象是一个比较重的操作,所以有些程序员会尽可能地减少new对象的次数,尝试减小堆的分配开销,减少内存碎片。
但是,短命对象的创建在JVM中比我们想象的性能更好,所以,不要吝啬new关键字,大胆地去new吧。
当然前提是不做无谓的创建,对象创建的速率越高,那么GC也会越快被触发。
结论:
分配小对象的开销分享小,不要吝啬去创建。
GC最喜欢这种小而短命的对象。
让对象的生命周期尽可能短,例如在方法体内创建,使其能尽快地在YoungGC中被回收,不会晋升(romote)到年老代(Old Generation)。
二、对象分配的优化
基于大部分对象都是小而短命,并且不存在多线程的数据竞争。这些小对象的分配,会优先在线程私有的 TLAB 中分配,TLAB中创建的对象,不存在锁甚至是CAS的开销。
TLAB占用的空间在Eden Generation。
当对象比较大,TLAB的空间不足以放下,而JVM又认为当前线程占用的TLAB剩余空间还足够时,就会直接在Eden Generation上分配,此时是存在并发竞争的,所以会有CAS的开销,但也还好。
当对象大到Eden Generation放不下时,JVM只能尝试去Old Generation分配,这种情况需要尽可能避免,因为一旦在Old Generation分配,这个对象就只能被Old Generation的GC或是FullGC回收了。
- Java程序员在编码过程中通常不需要考虑内存问题
- 许多Java程序员认为在编码过程中GC机制
- IOS开发过程中如何简单快速使用storyboard(不需要考虑适配问题)
- 编码中考虑的问题
- Java 中使用内存映射文件需要考虑的 10 个问题
- Java 中使用内存映射文件需要考虑的 10 个问题
- Java 中使用内存映射文件需要考虑的 10 个问题
- Java 中使用内存映射文件需要考虑的 10 个问题
- Java 中使用内存映射文件需要考虑的 10 个问题
- Java 中使用内存映射文件需要考虑的 10 个问题
- 在实际使用它的过程中不需要再次使用 ‘
- 【Java】编程过程中遇到的中文编码问题
- 程序在运行过程中内存的分配问题
- 构建大型业务系统过程中需要考虑的问题
- 读取文件,考虑编码问题
- java程序由于编码问题在cmd中运行失败
- 黑马程序员----Java内存问题
- 搜索过程中遇到的编码问题
- ubantu查找命令
- NKOI 1123 潜水员
- Spring框架 AOP (五)
- ACM程序设计选修课——Problem D: (ds:树)合并果子(最优二叉树赫夫曼算法)
- MyBatis分页拦截
- Java程序员在编码过程中通常不需要考虑内存问题
- js中如何自定义一个map集合
- 深入理解javascript原型和闭包系列 深入理解javascript原型和闭包(11)——执行上下文栈
- spring integration 里面加 http session
- HTML基础小结
- c/c++标准预定义宏 .
- HTTP请求中POST与GET的区别
- CoreData
- ReactiveCocoa