Java内存管理(一)综述

来源:互联网 发布:jquery处理json数据 编辑:程序博客网 时间:2024/05/17 19:17

        首先跟大家说明,Java一样会存在内存泄露问题

 

        大部分Java程序员在初学Java的时候就被告知,Java有自己的的优秀的垃圾回收机制来回收已经分配的内存,因此我们无需关心内存回收问题,所以大部分Java程序员便肆意的创建对象,挥霍Java程序的内存,导致系统性能很差。

        来呀,挥霍呀,反正有垃圾回收。 

        也正是Java向我们许下了垃圾回收这个美好的承诺,导致了Java的内存泄露更加隐蔽,不被程序员所注意到。

 

        所以我们要学会内存管理。


        而要学会内存管理,首先我们要了解Java创建对象时内存分配的细节JVM如何进行垃圾回收

        Java内存管理分为两个方面:内存分配和垃圾回收

        这里的内存分配指的是创建对象时JVM为该对象在堆内存中分配的内存空间。

        垃圾回收指的是当Java对象失去引用变成垃圾时,JVM的垃圾回收机制自动清理该对象,回收该对象占用的内存。

 

        JVM的垃圾回收机制是由后台的线程完成的,该线程非常消耗性能,如果创建大量对象,系统不断分配内存会使得系统中可用内存减少,同时大量已分配内存的回收增加了垃圾回收的负担,这都会降低程序性能。

 

        Java变量可以分为成员变量和局部变量两种。

        其中局部变量有形参,方法内的局部变量,代码块内的局部变量三种。

        局部变量作用时间很短暂,所有局部变量都是放在栈内存中保存的,不管其是基本类型的变量,还是引用类型的变量,都是存储在各自的栈区中

        引用类型变量所引用的对象则是存储在堆内存中

        这里要知道,引用类型变量和引用类型变量所引用的对象不是一个东西。


        比如 People person = new Person(“XXX”);

         

        main栈区的是引用类型变量,堆内存中的是引用类型变量所引用的对象。

 

        类体内定义的变量被称为成员变量。

        如果定义该成员变量时没有使用static修饰,该成员变量又被称为非静态变量或实例变量。

        如果使用了static修饰,则该成员变量又被称为静态变量或类变量。

        使用static修饰的成员变量是类变量,属于该类本身,没有使用static修饰的成员变量是实例变量,属于该类的实例(Java对象本身)。同一个JVM中,每个类只对应一个Class对象,JVM对一个Java类只初始化一次,但每个类可以创建多个Java对象

        因此,同一个JVM中一个类的类变量只需一块内存空间,当程序初始化类时为该类的类变量分配内存空间并执行初始化;但对于实例变量,每创建一次实例,就要为实例变量分配一块内存空间

 

        Java是面向对象的语言,当Java程序员通过new关键字创建Java对象时,JVM会在堆内存中为Java对象分配内存空间

        对于JVM的垃圾回收来机制来说,是否回收一个对象的标准在于,是否还有引用变量引用该对象,只要还有引用变量引用该对象,垃圾回收机制就不会回收它。

 

        当一个对象在堆内存中时,可以把它所处的状态分为三种:可达状态,可恢复状态,不可达状态

        当一个对象被创建后,有一个以上的引用变量引用它,程序可以通过该引用变量来调用该对象的属性和方法,这个对象就处于可达状态。

        如果程序中某个对象不再有任何引用变量引用它,它将先进入可恢复状态,此时程序无法再调用该对象的属性和方法。在这个状态下,系统的垃圾回收机制准备回收该对象所占用的内存。在回收该对象之前,系统会先调用可恢复状态对象的finalize方法进行资源清理,如果系统在调用finalize方法后,重新让一个以上引用变量引用了该对象,则这个对象再次成为可达状态,否则,该对象进入不可达状态。

        当一个对象永久性地失去引用,即调用该对象的finalize方法依然不能使该对象变为可达状态,则这个对象成为不可达状态,只有当一个对象处于不可达状态时,系统才会回收该对象的内存。

        


        回到文章开头说的,Java一样会存在内存泄露问题。

        那么什么是内存泄露,程序运行过程中会不断地分配内存空间,那些不再使用的内存空间应该即刻回收他们,从而保证系统可以再次使用这些内存。如果存在无用的内存没有被回收,那就是内存泄露

        对于Java程序而言,处于不可达状态的对象有垃圾回收机制负责回收,因此程序员不需要考虑他们。而有些对象,他们处于可达状态,但是程序不再使用他们,但他们所占用的内存空间不会被回收,那么这些对象就会产生内存泄露。

        Java的垃圾回收机制可以监控每个Java对象,当某个对象处于不可达状态时,就回收该对象所占用的内存;同时,垃圾回收机制还对内存进行监控,负责清理内存分配、回收中产生的内存碎片。



0 0