Java实践(三)---Java中JVM分析

1、垃圾收集

Java在创建对象时自动分配内存,并当该对象的引用不在时,释放这块内存。

Java中使用被称为垃圾收集器的技术来监视Java程序的运行,当对象不再使用时,就自动释放对象所使用的内存。Java使用一系列软指针(这些指针并不是直接指向对象的,而是指向对象的引用)来跟踪对象的各个引用,并用一个对象表将这些软指针映射为对象的引用

垃圾收集器自动运行,一般情况下,不需要显式地请求垃圾收集器。调用System类中的静态方法gc(),可以运行垃圾收集器,但这样并不能保证立即回收指定对象

程序运行时,垃圾收集器会不时的检查对象的各个引用,并回收无引用对象所占的内存

Tips:Java语言并不要求JVM有gc,也没有规定gc如何工作,不过常用的JVM都有gc,而且有多数gc都使用类似的算法管理内存和执行收集操作。Java的垃圾回收机制是为所有的Java应用程序服务的,而不是为某个特定进程服务。

在JVM垃圾收集器收集任何一个对象之前,一般要求程序调用适当的方法来释放资源,但在没有明确释放资源的情况下,Java提供了默认机制终止化该对象来释放资源,这个方法是finalize()【portected void finalize()throws Throwable】。在finalize()方法返回之后,对象消失,垃圾收集开始执行。

在Java语言中,判断一块内存是否符合垃圾收集器收集标准的标准只有2个:
1、 给对象赋予了空值null,以后在没有调用过
2、给对象赋予了新值,即重新分配了内存空间

2、栈

1.基本数据类型直接在栈中分配空间
2.局部变量(在方法代码段中定义的变量)也在栈中直接分配空间,当局部变量所在方法执行完成之后该空间便立刻被JVM回收
3.引用数据类型,用关键字new创建出来的对象所对应的引用也是在栈空间中,此时,JVM在栈空间中给对象引用分配了一个地址空间,在堆空间中给该引用的对象分配一个空间,栈空间中的地址引用指向了堆空间中的对象区

3、堆

用来存放用关键字new出来的数据


堆内存的详细分析:http://blog.csdn.net/Wee_Mita/article/details/71070773

通过程序进行讲解:

package demo;
public class Student 
{
    private String name;
    private int age;
    public void study() 
    {
        System.out.println("I love study!");
    }
    public String getName() 
    {
        return name;
    }
    public void setName(String name) 
    {
        this.name = name;
    }
    public int getAge()
     {
        return age;
    }
    public void setAge(int age)
     {
        this.age = age;
    }
}
package demo;
public class StudentDemo 
{
    public static void main(String[] args) 
    {
        Student student = new Student();
        System.out.println(student.getName() + ":" + student.getAge());
        student.setName("John");
        student.setAge(23);
        System.out.println(student.getName() + ":" + student.getAge());
        student.study();
        Student student2 = student;
        student2.setName("Jack");
        student2.setAge(25);
        System.out.println(student2.getName() + ":" + student2.getAge());
        System.out.println(student.getName() + ":" + student.getAge());
    }
}

当我们运行程序时,JVM会把Student类与StudentDemo类编译完然后加载到JVM中一个叫方法区的地方,类的成员变量与成员方法也被加载到方法区中,此时内存模型如下:
这里写图片描述
可以看到study方法右边各有一个16进制的标记,而name与age变量没有,这是因为每个对象都有各自的成员变量,而类中的成员方法却可以被每个对象所共用,为了节省内存空间,JVM为方法分配了该标记(也叫内存地址)便于每个new出来的对象查找调用,接着JVM会自动寻找main方法,在栈中为main方法申请一个空间,这个过程也叫入栈,然后执行我们Student类中第4行代码,这时候,JVM在堆空间中分配一块内存给Student对象,并为其分配一个内存地址(如果对象的成员变量没有赋值,则JVM会为变量赋初始值),在栈中分配一块内存空间用于指向堆空间中的Student对象区的内存地址,此时内存模型如下:
这里写图片描述
接着看代码第8行与第9行,程序为student对象的成员变量赋值,JVM会根据student所指向的地址在堆内存中寻找Student类的变量,并为变量赋新的值
这里写图片描述
第11行,这时student对象调用study方法,JVM在栈空间中为study方法申请了一块内存空间
这里写图片描述
study方法执行完后,立即释放栈空间,代码第12行,student2对象的引用指向了student所指向的地址
这里写图片描述
代码13与14行,为student2的变量赋值,由于student2与student指向了同一个地方,所以这时student对象中变量的值也被改变
这里写图片描述
到这,main方法中所有代码执行完毕,main方法所占用的栈空间也被回收,而堆空间等待GC(Generational Collectiing)【分代收集】回收
这里写图片描述
代码执行结果如下:

    null:0
    John:23
    I love study!
    Jack:25
    Jack:25
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值