关于Java内存溢出的一些思考
来源:互联网 发布:android锁机源码 编辑:程序博客网 时间:2024/05/22 06:22
Java中是否有内存溢出的问题?
我们都知道,JVM中提供了GC的机制来帮助内存的管理,使得Java不必像C++般必须由程序员主动销毁对象,释放被占用空间。GC具有主动性,也可以被调用。但GC的这种主动回收内存垃圾的“主动性”如何?效率如何?
主动性的问题:垃圾回收器“主动”回收内存垃圾的时候,必是濒临内存资源用完的时刻。为什么呢?因为垃圾回收器本身也是占用资源的“一个线程”,它的启动必然带来资源的开销,所以一般情况下,垃圾回收器不被愿意带有“主动性”。
通过调用(System.gc()、Runtime.getRuntime().gc()):程序员主动调用垃圾回收。
那么,在上述愿景下,是否可以防止内存溢出或泄露的问题呢?
考虑两种情况:1.一次加载过多的对象;2.内存中存在”不可回收的“对象或内存区域。
第一种情况呢,是可能的(是一个”out of menory exception“的错误)。
第二种情况呢,需要了解一些东西。
java不像C或C++,有指针这东西。而是靠”引用“,来维持栈与内存堆中的联系(如,Object o = new Object(),在内存堆中分配了部分空间给Object对象(new Object()),然后在栈中添加该Object对象的引用o(Object o),并指向该内存空间(= )。(至于,“栈是运行时单位,而堆是存储的单位”这句话,与内存堆的回收有关。)”引用“是有分类的:强引用、软引用、弱引用、虚引用。不同的引用类型,在GC下,垃圾回收器的对待是不一致的。
(1)强引用下,对象不可回收。
(2)软引用下,视乎当前内存的使用状况,相当有余则不回收。另外,在OutOfMomery的情况下,必定被回收。
(3)弱引用下,GC启动则回收。
(4)虚引用下,与弱引用类似,虚引用与弱引用的一个区别在于:虚引用必须和引用队列(ReferenceQueue)联合使用。使用的唯一目的是:对象被回收时返回一个系统通知。
不同的引用特性,决定了对象的使用及生命周期。所以,在当前引用对象均为强引用的情况下,及时GC启动,也无济于事。
今天翻看《Java编程思想(第四版)》,看到这3句话(第四章第五节):
1.对象可能不被垃圾回收。
2.垃圾回收并不等于“析构”(C++的说法)。
3.垃圾回收只与内存有关。
还有一个问题:垃圾回收器只知道释放经由new分配的内存,而如果某些内存块不是由new产生,那这种“特殊”的内存区域,该如何释放呢?
new是java中创建对象的唯一方式。java也宣称”一切都是对象“。但,真的一切都是对象吗?基本数据类型就不是(如int、char等)。当然,为了把基本数据类型也包含进”对象“的范畴,java推出了基本数据类型的包装类(如Integer、Char等)。那么该如何对这些非new的该如何回收?要引出这一点,new出来的对象是存放在内存堆中的。那么非new的,会放置在哪呢?栈!就好像栈中存放对象的引用一般,对象的引用是对内存堆真实对象的联系维护。更真实的是,这个引用,实际上就是一个值,一个内存堆中对象的存储空间值。是个基本类型的数据?我相信是。所以说,非new的存放于栈中就很自然了。那这个栈会怎么样回收呢?其实也很简单,就是判断是否有相关“引用”指向这个常量,无则清除掉。
另外,有说明的一点是,为什么会选取在栈中存放基本类型的数据。这样说吧,基本类型数据的可占用空间大小是固定的(如int占用4字节等),并且占用不大。而对象呢,光是纯Object对象就占用8byte,一个Integer就占用12byte...并且大多数对象的可占用大小是未知而庞大的,故必须放置在内存堆中,进行动态管理。
真正关于垃圾回收的话题、方式也很多,不过这里就先只讨论下”溢出“的问题,感兴趣的也可以看看下面的参考资料,有话及的相关内容。该文主要在于对过往的整理,不足处望指正。
参考:《Java编程思想(第四版)》
《JVM调优总结.pdf》——作者:和你在一起(http://pengjiaheng.javaeye.com)
《疯狂Java:突破程序员基本功的16课》
- 关于Java内存溢出的一些思考
- 关于内存溢出的一些问题
- 关于一个整型参数内存溢出的思考
- 关于JAVA中内存溢出的解决办法
- 关于JAVA中内存溢出的解决办法
- 关于Java中内存溢出的解决办法
- 关于JAVA中内存溢出的解决办法
- 关于JAVA中内存溢出的解决办法
- 关于JAVA中内存溢出的解决办法
- 关于JAVA中内存溢出的解决办法
- 关于数组溢出的思考
- java内存管理的一些基础,内存溢出的解决方案。。。
- 关于一些异常内存溢出的问题分析
- 一些关于内存缓冲区溢出的保护机制
- 关于 Java EE 的一些思考
- 关于java中Static的一些思考
- 关于Java类的一些思考
- 关于java与C的一些思考
- poj1112 Team Them Up!
- MIRA BAPI BAPI_INCOMINGINVOICE_SAVE
- 我的软件开发之路(一)
- SQL Server经典语句
- 【校园招聘】一道笔试题看c++中virtual覆盖
- 关于Java内存溢出的一些思考
- oracle数据管理
- 编写一个关于星期几的枚举WeekDay
- Linux 串口编程--转载一篇解决了困扰我一个星期问题的文章
- java中Socket应用
- 晚安!记住这个幸福号码:15811112530
- ASP入门1
- python使用suds调用webservice
- 算法学习--分治法