应用程序对资源(内存使用)管理的方式,常见的一般有如下几种:
1、手动管理:C,C++
2、计数管理:COM
3、自动管理:.NET,Java,PHP,GO…
但是,手动管理和计数管理的复杂性很容易产生以下典型问题:
1.程序员忘记去释放内存
2.应用程序访问已经释放的内存
三、GC如何工作:
GC的工作流程主要分为如下几个步骤:
1、标记(Mark)---GC的根节点也即GC Root
2、计划(Plan)
3、清理(Sweep)
4、引用更新(Relocate)
5、压缩(Compact)
在Java中,可以当做GC Root的对象有以下几种:
1、虚拟机(JVM)栈中的引用的对象
2、方法区中的类静态属性引用的对象
3、方法区中的常量引用的对象(主要指声明为final的常量值)
4、本地方法栈中JNI的引用的对象
四、什么时候发生GC;
1、当应用程序分配新的对象,GC的代的预算大小已经达到阈值,比如GC的第0代已满
2、代码主动显式调用System.GC.Collect()
3、其他特殊情况,比如,windows报告内存不足、CLR卸载AppDomain、CLR关闭,甚至某些极端情况下系统参数设置改变也可能导致GC回收
五、建议:
由于GC的代价很大,平时开发中注意一些良好的编程习惯有可能对GC有积极正面的影响,否则有可能产生不良效果。
1、尽量不要new很大的object,大对象(>=85000Byte)直接归为G2代,GC回收算法从来不对大对象堆(LOH)进行内存压缩整理,因为在堆中下移85000字节或更大的内存块会浪费太多CPU时间。
2、不要频繁的new生命周期很短object,这样频繁垃圾回收频繁压缩有可能会导致很多内存碎片,可以使用设计良好稳定运行的对象池(ObjectPool)技术来规避这种问题。
3、使用更好的编程技巧,比如更好的算法、更优的数据结构、更佳的解决策略等等。