java中引用类型
- 强引用
Persnon p = new Person();
当指向Person对象的引用计数为0时,Person对象才能被垃圾回收器回收。
- 软引用
SoftReference<Person> sr = new SoftReference<Person>(new Person());
获取软引用对象Person p = sr.get();
当内存紧张的情况下,Person对象可能会被回收,即使它的引用计数为1
- 弱引用
WeakReference<String> w = new WeakReference<String>(new string());
获取软引用对象String str = w.get();
随时可能被垃圾回收器回收
- 虚引用
引用队列:当软引用或者是弱引用指向的对象被释放后,会将引用放在引用队列中(ReferenceQueue)。
虚引用是先将引用加入队列中再释放对象。
ReferenceQueue<String> rq = new ReferenceQueue<String>();
PhantomReference<String> pr = new PhantomReference<String>(new String(), rq);
//pr.get() 为null rq.poll为pr
虚引用其实就是形同虚设,和没引用一样。其作用就是来检查对象是否将要被回收。并且没有get()方法来获取传入的对象。
注:以上的sr,w, rq都强引用,指向不同对象,而在这些对象内补使用不同的引用指向我们传入的对像。
JAVA内存泄露
C中通过malloc()函数申请的内存不free()的话就会引起内存泄露。JAVA中的内存泄露是创建的对象只使用一次,今后再也不会使用,但没有将其引用计数置为0(强引用),就会发生内存泄露。
内存泄露代码:
public class Stack {
private Object[] elementData;
private int size = 0;
private int capacityIncrement;
public Stack(int initialCapacity){
elementData = new Object[initialCapacity];
}
public Stack(int initialCapacity, int capacityIncrement){
this(initialCapacity);
this.capacityIncrement = capacityIncrement;
}
public void push(Object object){
ensureCapacity();
elementData[size++] = object;
}
public Object pop(){
if(size == 0){
throw new RuntimeException("空栈");
}
return elementData[--size];
}
private int size(){
return size;
}
private void ensureCapacity(){
if(elementData.length == size){
Object[] oldElements = elementData;
int newLength = 0;
if(capacityIncrement > 0){
newLength = elementData.length + capacityIncrement;
}else{
newLength = (int)(elementData.length *1.5);
}
elementData = new Object[newLength];
System.arraycopy(oldElements, 0 , elementData, 0 , size);
}
}
public static void main(String[] a){
Stack stack = new Stack(10);
for(int i=0; i<10; i++)
stack.push("element" + i);
for (int i=0; i<10; i++) {
System.out.println(stack.pop());
}
}
}
private Object[] elementData;
private int size = 0;
private int capacityIncrement;
public Stack(int initialCapacity){
elementData = new Object[initialCapacity];
}
public Stack(int initialCapacity, int capacityIncrement){
this(initialCapacity);
this.capacityIncrement = capacityIncrement;
}
public void push(Object object){
ensureCapacity();
elementData[size++] = object;
}
public Object pop(){
if(size == 0){
throw new RuntimeException("空栈");
}
return elementData[--size];
}
private int size(){
return size;
}
private void ensureCapacity(){
if(elementData.length == size){
Object[] oldElements = elementData;
int newLength = 0;
if(capacityIncrement > 0){
newLength = elementData.length + capacityIncrement;
}else{
newLength = (int)(elementData.length *1.5);
}
elementData = new Object[newLength];
System.arraycopy(oldElements, 0 , elementData, 0 , size);
}
}
public static void main(String[] a){
Stack stack = new Stack(10);
for(int i=0; i<10; i++)
stack.push("element" + i);
for (int i=0; i<10; i++) {
System.out.println(stack.pop());
}
}
}
在pop()函数中存在内存泄露,当弹出一个元素时,并没有将数组的引用置为null