静态内存
在Java中静态内存分配是指在Java被编译时就已经能够确定需要的内存空间,当程序被加载时系统把内存一次性分配给它。这些内存不会在程序执行时发生变化,直到程序执行结束时内存才会被回收。在Java的类和方法中的局部变量包括原生数据类型和对象的引用都是静态分配内存的。静态内存空间实在Java栈上分配的,当方法运行结束时,对应的栈帧也就撤销了,所以分配的静态内存空间也就被回收了。
// 形参 arg 为基础数据类型int 4个字节
public void test(int arg) {
// 对象引用 4个字节(对象引用一律为4个字节表示内存地址)
String s = "helloword";
// 基础数据类型 long 8个字节
long l1 = 1;
// 对象引用 4个字节
Long l2 = 1L;
}
动态内存
除了Java基础数据类型,其他都是对象类型,它们存储在Java堆中,可以被共享,不一定随着方法执行结束而消失。对于对象类型,在Java栈中会分配一个4字节的地址指针空间(引用),这个地址指针指向该对象在堆中的地址。
对象的内存空间是动态分配的,即只有在程序执行时才知道要分配的存储空间大小,这个对象什么时候被回收也是不确定的,只有等到这个对象不再使用时才会被回收。动态内存的分配和回收是一个值得讨论的问题,下面就看看垃圾收集器(下面简称GC)是怎样来解决堆内存回收的。
检测垃圾
GC的第一个使命就是正确地检测出垃圾对象,这也是关键点。先给出垃圾对象的定义:不能够被一个根对象集合到达的对象。根对象集合和JVM的具体实现有关系,但大都包含如下元素:
1)静态属性引用的对象
2)虚拟机栈中的引用对象
3)在本地方法中持有的对象引用:有些对象被传入本地方法中,但是这些对象还没有被释放
对于引用,补充说明一点。上面说的引用指的是强引用,在Java中有四种引用类型,如下:
1)强引用:是指创建一个对象并把这个对象赋给一个引用变量, 强引用有引用变量指向时永远不会被垃圾回收,JVM宁愿抛出OutOfMemory错误也不会回收这种对象。
2)软引用:如果一个对象具有软引用,内存空间足够,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。软引用可用来实现内存敏感的高速缓存,比如网页缓存、图片缓存等。使用软引用能防止内存泄露,增强程序的健壮性。
3)弱引用:弱引用也是用来描述非必需对象的,当JVM进行垃圾回收时