java的内存分配策略有静态、栈和堆三种。静态存储分配在编译时确定所有变量的存储要求;栈式存储分配要求在模块的入口处确定所有存储要求;堆式存储分配则专门负责在编译时或运行时模块入口处都无法确定存储要求的数据结构的内存分配。堆由大片的可利用块或空闲块组成,堆中的内存可以按照任意顺序分配和释放。
编程中,栈主要是用来执行程序,堆主要用来存放对象。所有的方法调用都是通过栈来进行的,所有的局部变量,形式参数都是从栈中分配内存空间。堆是应用程序在运行的时候请求操作系统分配给自己内存,分配和销毁内存时都要占用时间,因此用堆的效率低。但是堆的优点在于不必知道要从堆里分配多少存储空间,也不必知道存储的数据要在堆里停留多长的时间,因此,用堆保存数据时会得到更大的灵活性。
java中的基本数据类型有byte,short,char,int,long,float,double,boolean等,基本数据类型存储在栈中,用==进行比较。
创建复合数据类型时将引用变量存放在栈中的地址,在堆中存放对象,引用变量的取值等于对象在堆内存中的首地址。用==比较两个复合数据类型时,比较的是这两个复合数据类型在栈中存放的地址。堆中存放的对象在没有引用变量指向它时变为垃圾,随后随机被GC回收内存。
public boolean equals(Object obj) {
return (this == obj);
}
Object类中的equals方法,可以看到Object中equals方法实际上与==等效,仍然比较的是栈中的地址。
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}
return false;
}
String类改写的equals方法,判断两个String是否有相同的值。
字符串缓冲池:程序在运行的时候会创建一个字符串缓冲池,创建字符串的时候,程序首先会在这个String缓冲池中寻找相同值的对象,如果存在相同的值,则新的引用也指向这个相同的值。