Java内存分配和垃圾回收机制_Java的初始化机制、垃圾回收机制和内存分配机制...

先看初始化的例子

publicclassParent

{

staticTipout TIP =newTipout("父类 static 成员 TIP 初始化");

Tipout tip =newTipout("父类 成员 tip 初始化");

publicParent()

{

System.out.println("父类 构造函数 调用");

}

}

classSubextendsParent

{

staticTipout SUB_TIP =newTipout("子类 static 成员 SUB_TIP 初始化");

Tipout subTip =newTipout("子类 成员 subTip 初始化");

publicSub()

{

System.out.println("子类 构造函数 调用");

}

}

classTipout

{

publicTipout(String s)

{

System.out.println(s);

}

}

执行结果:

父类 static 成员 TIP 初始化

子类 static 成员 SUB_TIP 初始化

父类 成员 tip 初始化

父类 构造函数 调用

子类 成员 subTip 初始化

子类 构造函数 调用

由此可以总结出java初始化的顺序:

->所有静态成员初始化(父类->子类)

-->父类初始化(普通成员->构造函数)

--->子类初始化(普通成员-->构造函数)

!static成员初始化顺序只和类定义中的顺序有关。

调用静态数据和静态方法时,这个类中的所有静态成员都会被初始化(非static成员不会被初始化),前提是他们从未被初始化过。

publicclassParent

{

publicstaticTipout TIP =newTipout("父类 static 成员 TIP 初始化");

static

{

System.out.println("父类 static 代码块");

}

Tipout tip =newTipout("父类 成员 tip 初始化");

publicParent()

{

System.out.println("父类 构造函数 调用");

}

publicstaticvoidoutMsg(){

System.out.println("父类 static 函数 调用");

}

}

在Main()中调用:Parent.TIP.toString();

结果:

0818b9ca8b590ca3270a3433284dd417.png

垃圾回收:

java中并不需要清除对象,也不存在C++中的析构函数,java的垃圾回收机制会自动释放无用的变量。

一个对象,可以有一个或多个引用变量指向它。当一个对象不再有任何一个引用变量指向它时,这个对象可以被垃圾回收机制回收了。

但是,并不是对象被抛弃后当即被回收的。JVM进程做空间回收有较大的系统开销。如果每当某应用进程丢弃一个对象,就立即回收它的空间,

势必会使整个系统的运转效率非常低下。

!不能操纵垃圾回收

使对象值为null,或者调用System.gc()

JVM接受这个消息后,并不是立即做垃圾回收,而只是对几个垃圾回收算法做了加权,使垃圾回收操作容易发生,或提早发生,或回收较多而已。

!垃圾回收器的运行时间是不固定的,清理工作的实际运行时间也是不能预知的。

内存分配机制

2.3.1Java 把内存划分成两种:

1.栈内存,

基本类型的变量和对象的引用变量(存取速度比堆要快,仅次于寄存器)

2.堆内存。

堆内存用来存放由 new 创建的对象和数组。

!类跟数组一样,都是属于引用类型,引用类型就是指一堆对内存可以同时被多个栈内存指向。

java中主要存在4块内存空间:

栈内存空间:保存所有的对象名称(更准确地说是保存了引用的堆内存空间的地址)

堆内存空间:保存每个对象的具体属性内容。

全局数据区:保存static类型的属性。

全局代码区:保存所有的方法定义。

2.3.2 String缓冲池

缓冲池是java为了节省内存空间,会在内存中创建一个专门为String设计的缓冲池,用来保存已经存在的字符串,

如果2个字符串是一样的,则使用池中的字符串,不再创建新的对象

用下边的代码测试:

String str1 = "abc";

String str2 = "abc";

System.out.println(str1==str2); //true

结果为true,说明str1和str2指向同一个对象

String str1 =new String ("abc");

String str2 =new String ("abc");

System.out.println(str1==str2); // false

用new则在堆中创建了2个对象

2.4应该注意的问题:

1.使用以下方式创建字符串

String str = "hello";

上面这种方式会创建一个"hello"字符串,而且JVM的字符缓存池还会缓存这个字符串。

String str = new String("hello");

此时程序除创建字符串外,str所引用的String对象底层还包含一个char[]数组,这个char[]数组依次存放了h,e,l,l,o

2.尽量减少对变量的重复计算

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值