重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
作者:RednaxelaFX
成都创新互联是一家专注于做网站、成都网站建设与策划设计,万源网站建设哪家好?成都创新互联做网站,专注于网站建设十多年,网设计领域的专业建站公司;建站业务涵盖:万源等地区。万源做网站价格咨询:18982081108
链接:
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Java怎样的编程习惯有利于GC,这硬要扣细节的话一定要结合具体的JVM实现才可以分析,因为各个JVM甚至同一个JVM里的各个GC实现都会有不同的特点。
但通用的、通常管用的建议,其实很简单:
写简单直观的代码,不要玩花招。过分设计、过多的封装/抽象层,常常会让GC很难受(导致需要处理的对象增多)。
要理解:GC是伙伴,不是仆人。在保持代码结构良好、直观易懂的前提下,减少没必要的对象分配总是好的。
不要调用System.gc() - 可能影响GC的统计数据和未来决策
不要随意使用“对象池” - 为了优化GC而使用对象池常常是非常有害的。为了别的有用的目的,例如说持有初始化开销高的资源而使用对象池,这才是通常可取的场景。
通常不用关心对局部变量置null - 开头的传送门有详细讲解
小心使用ThreadLocal,特别是当跟线程池搭配使用的时候 - 如果用线程池来跑任务,而这些任务向ThreadLocal写入了数据,那么应该注意在任务完成时清理ThreadLocal,不然容易泄漏
如果使用堆外内存来实现Java对象的缓存,而且在堆外内存里存的是序列化后的Java对象的话,要小心使用时的反序列化开销及其伴随的频繁创建对象的开销。
如果程序里有使用NIO,要关注DirectByteBuffer的使用状况;例如说如果禁用了System.gc()并且程序调优过使得GC频率非常低的话,死掉的DirectByteBuffer可能会得不到及时的释放。请参考这个传送门的第1点:[HotSpot VM] JVM调优的"标准参数"的各种陷阱
经常查看与分析GC日志(或者通过别的方式,例如JMX,来做类似的监控) - 没问题就别乱优化,有问题要及时发现和分析
关于GC是伙伴不是仆人:意思是说,虽然很偶尔会遇到GC自身有bug而导致内存泄漏,但一般来说还是可以信任JVM的GC可以收集程序不需要的所有垃圾对象的。但这应该是一个双向沟通(伙伴)的模型,而不是一个单向发出命令(仆人)的模型。我们可以写程序,GC会知道要收集哪些对象;反过来,GC会给我们反馈(GC日志、JMX监控,等等),告诉我们它表现得如何,是否需要我们的帮助来改进它的表现。
BufferedReader 的缓存开大一点;
或者如果确定文件大小,一次性读进一个byte[] 用ByteArrayInputStream 包起来
Java的公有API可以主动调用GC的有两种办法,一个是
System.gc();
// 或者下面,两者等价
Runtime.getRuntime().gc();
还有一个是JMX:
java.lang.management.MemoryMXBean.gc()
作用跟System.gc()也是类似的。
MemoryMXBean.gc()和System.gc()的内部实现都是Runtime.getRuntime().gc(),从效果上说两者一模一样没有区别。
程序员是无法让System.gc();按照规则调用的,你可以在程序启动过程中写上这段代码,不过至于什么时候调用就要看JVM了.
不过,觉得你的程序或许应该有地方资源泄漏了吧,假如你的机器是2G内存,一般运行WindowsXP,大概也就用1/4内存,再加上的JVM,1G应该搞定了,剩下的1G,你用来加载信息,个人觉得,如果启动就死是不太可能的,如果运行一段时间,程序写的不完善可能会死掉,个人建议你还是好好看看自己的程序吧,如果确认程序没问题,那就只有加内存了,没有别的办法,光靠JVM的垃圾回收,效果不是很多.