OutOfMemoryErr: 高薪的垃圾收集器

本文通过实例探讨Java中内存管理及垃圾回收机制的工作原理。分析了如何触发内存溢出异常及利用异常辅助管理对象生命周期的可能性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 现在我们一起来看一个看起来幼稚但却又很容易被人忽略的程序:

程序要求:创建一个大小为 100 MB byte类型的数组:<o:p></o:p>

public class  OutOfMemory<o:p></o:p>

{<o:p></o:p>

        public static void main(String args[])<o:p></o:p>

               {<o:p></o:p>

                      byte  b = new  byte[1024*1024*100] ;<o:p></o:p>

               }<o:p></o:p>

}<o:p></o:p>

<o:p> </o:p>

运行会报出如下的错误 OutOfMemoryError Java  heap  space

<o:p></o:p>

(实际上是在byte[]的大小不能超过58 MB ,对于 int[] 类型的大小不能超过14 MB ,也就是说不同类型的数组的最大length 的限度也是不同的)<o:p></o:p>

<o:p> </o:p>

<v:shapetype o:spt="75" coordsize="21600,21600" stroked="f" id="_x0000_t75" filled="f" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe"><v:stroke joinstyle="miter"></v:stroke><v:formulas><v:f eqn="if lineDrawn pixelLineWidth 0"></v:f><v:f eqn="sum @0 1 0"></v:f><v:f eqn="sum 0 0 @1"></v:f><v:f eqn="prod @2 1 2"></v:f><v:f eqn="prod @3 21600 pixelWidth"></v:f><v:f eqn="prod @3 21600 pixelHeight"></v:f><v:f eqn="sum @0 0 1"></v:f><v:f eqn="prod @6 1 2"></v:f><v:f eqn="prod @7 21600 pixelWidth"></v:f><v:f eqn="sum @8 21600 0"></v:f><v:f eqn="prod @7 21600 pixelHeight"></v:f><v:f eqn="sum @10 21600 0"></v:f></v:formulas><v:path gradientshapeok="t" o:extrusionok="f" o:connecttype="rect"></v:path><o:lock v:ext="edit" aspectratio="t"></o:lock></v:shapetype><v:shape type="#_x0000_t75" id="_x0000_i1025" style="WIDTH: 405pt; HEIGHT: 209.25pt"><v:imagedata src="file:///C:\DOCUME~1\ADMINI~1.IBM\LOCALS~1\Temp\msohtml1\01\clip_image001.jpg" o:title="OutOfMemory"></v:imagedata></v:shape><o:p></o:p>

解析:<o:p></o:p>

java.lang.OutOfMemoryError内存不足)

Thrown when the Java Virtual Machine cannot allocate an object because it is out of memory, and no more memory could be made available by the garbage collector<o:p></o:p>

JAVA 虚拟机没有足够的内存分配给对象,垃圾收集器也没有多余的内存可供使用时,将报出 java.lang.OutOfMemoryError <o:p></o:p>

<o:p> </o:p>

呵呵 !看到这或许有人会说谁会犯这么低级的错误啊 ?但是想想你在平时是不是经常用到一些类似这样的语句: <o:p></o:p>

InputStream xmlStream = new FileInputStream("data/workflow1.xml");<o:p></o:p>

       byte[] datas = new byte[xmlStream.available()];<o:p></o:p>

呵呵。在看这些程序的时候是不是觉得是那么的眼熟,那么的合理可是细想想是不是有可能和我们上面的程序犯同样的一个错误  ?呵呵  <o:p></o:p>

<o:p> </o:p>

不过这样的程序给了我另一个想法 <o:p></o:p>

思考:<o:p></o:p>

no more memory could be made available by the garbage collector:<o:p></o:p>

(?):也就是说在程序抛出异常之前应该会去调用了System. finalize( )方法,回收一些不再使用的对象吗?呢么我们可以怎么应用 java.lang.OutOfMemoryError 能不能用OutOfMemoryError来管理对象的生命周期呢 <o:p></o:p>

<o:p> </o:p>

先试试看:JAVA自带的垃圾回收机制,是不是能够及时的进行垃圾回收  <o:p></o:p>

例子1<o:p></o:p>

public class Person

{

<o:p> </o:p>

       public void finalize()

       {

              System.out.println("The object is going !");

       }

/**

*   main( ) 中创建了三个 Person( )

*/

       public static void main(String[] args)

       {

              new Person();<o:p></o:p>

              new Person();<o:p></o:p>

              new Person(); <o:p></o:p>

//   new Person();    读者可以将这行的注释符号去掉,再运行试试 ,将有另一个结果!<o:p></o:p>

              System.out.println("The program is ending !");

<o:p> </o:p>

       }

}<o:p></o:p>

运行结果:<o:p></o:p>

<v:shape type="#_x0000_t75" id="_x0000_i1026" style="WIDTH: 414.75pt; HEIGHT: 213pt"><v:imagedata src="file:///C:\DOCUME~1\ADMINI~1.IBM\LOCALS~1\Temp\msohtml1\01\clip_image003.png" o:title=""></v:imagedata></v:shape>

<o:p> </o:p>

<o:p> </o:p>

(?)这是怎么回事啊 finalize() 怎么没有被调用啊 <o:p></o:p>

 原来,  JAVA的垃圾回收机制是非常懒惰的,只有在对象向堆所请求的内存不足,垃圾收集器(Garbage Collector)才会启动,释放那些引用数为零的对象所占用的内存,Java不会自动释放无用的对象的引用。

<o:p> </o:p>

那么我们修改例子1代码:

import java.lang.Exception;

<o:p> </o:p>

       public class Person

{

<o:p> </o:p>

       public void finalize()

       {

              System.out.println("The object is going !");

       }

<o:p> </o:p>

       public static void main(String[] args)throws Exception

       {

              new Person();        <o:p></o:p>

              try<o:p></o:p>

                     {<o:p></o:p>

                            int by[] = new int[1024*1024*15];<o:p></o:p>

                       System.out.println("OK");<o:p></o:p>

                     }<o:p></o:p>

                     catch(Exception e)<o:p></o:p>

                     {<o:p></o:p>

                       e.printStackTrace();<o:p></o:p>

                     }     <o:p></o:p>

        }          

       }           

查看运行结果:

<v:shape type="#_x0000_t75" id="_x0000_i1027" style="WIDTH: 414.75pt; HEIGHT: 293.25pt"><v:imagedata src="file:///C:\DOCUME~1\ADMINI~1.IBM\LOCALS~1\Temp\msohtml1\01\clip_image005.png" o:title="3"></v:imagedata></v:shape>

看来java.lang.OutOfMemoryErr帮助我们收垃圾了 !(只不过这个收垃圾的工资要求太高了)。

<o:p> </o:p>

思考:( 想法不一定可行 )<o:p></o:p>

我们可否用 Error 或者 Exception 来控制对象的生命周期呢 ,OutOfMemoryErr 这样收垃圾的未免有点太高销了,怎么寻找一个低廉的Err 或者 Exception <o:p></o:p>

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值