1.
分配
释放
这样做加重了JVM的工作。因为,GC为了能够正确释放对象,GC必须监控每一个对象的运行状态,包括对象的申请、引用、被引用、赋值等,GC都需要进行监控。
2.
在Java中,内存泄漏就是存在一些被分配的对象,这些对象有两个特点:1.这些对象是可达的,即在有向图中,存在通路可以与其相连(也就是说仍存在该内存对象的引用);2.这些对象是无用的,程序以后不会再使用这些对象。
如果对象满足这两个条件,这些对象就可以判定为Java中的内存泄漏,这些对象不会被GC所回收,然而它却占用内存。
3.
java内存分两种:栈内存、堆内存
3.1.在函数中定义的基本类型、对象的引用类型变量都在函数的栈内存中分配;
3.2.由new创建的对象、数组、对象的实例变量放在堆内存
在函数(代码块)中定义一个变量时,java在栈中为这个变量分配内存空间,当超过变量的作用域后java会自动释放掉为该变量所分配的内存空间;在堆中分配的内存由java虚拟机的自动垃圾回收器来管理
4.堆和栈的优缺点
缺点是 要在运行时动态分配内存,存取速度较慢.
4.2栈的优势是 存取速度比堆要快,仅次于直接位于CPU中的寄存器。栈数据可以共享
缺点是 栈中的数据大小与生存期必须是确定的,缺乏灵活性。
5.
5.1基本数据类型
基本数据类型8种,如int
定义完a与b的值后,再令a
5.2 对象
在Java中,创建一个对象包括对象的声明和实例化。下面用一个例题来说明对象的内存模型。
假设类Rectangle定义如下:
public
double
double
public
w
h
}
}
1.声明对象时的内存模型
Rectangle
但Rectangle的值为空,rect是一个空对象。空对象不能使用,因为它还没有引用任何"实体"。
2.对象实例化时的内存模型
当执行rect=new
在堆内存中为类的成员变量width,height分配内存,并将其初始化为各数据类型的默认值;接着进行显式初始化(类定义时的初始化值,调用构造方法)为成员变量赋值。返回堆内存中对象的引用(相当于首地址)给引用变量rect,以后就可以通过rect来引用堆内存中的对象了。
3.
一个类通过使用new运算符创建多个不同的对象实例,这些对象实例将在堆中被分配不同的内存空间,改变其中一个对象的状态不会影响其他对象的状态。
Rectangle
Rectangle
此时,将在堆内存中分别为两个对象的成员变量width、height分配内存空间,两个对象在堆内存中占据的空间是互不相同的。如果有:
Rectangle
Rectangle
则在堆内存中只创建了一个对象实例,在栈内存中创建了两个对象引用,两个对象引用同时指向一个对象实例。
4.包装类 基本类型的定义在栈中,包装类创建对象,就和普通对象一样了。
5.
第一种创建方式,和普通对象的的创建过程一样;
第二种创建方式,Java内部将此语句转化为以下几个步骤:
(1)
(2)
(3)
值得注意的是,一般String类中字符串值都是直接存值的。但像String
合下,其字符串值却是保存了一个指向存在栈中数据的引用。
为了更好地说明这个问题,我们可以通过以下的几个代码进行验证。
String
String
System.out.println(s1==s2);//true
注意,这里并不用str1.equals(str2);的方式,因为这将比较两个字符串的值是否相等。==号,根据JDK的说明,只有在两个引用都指向了同一个对象时才返回真值。
我们再接着看以下的代码。
String
String
System.out.println(str1==str2);//false
创建了两个引用。创建了两个对象。两个引用分别指向不同的两个对象。
6.数组
当定义一个数组,int
7.静态变量
静态表示的是内存的共享,就是它的每一个实例都指向同一个内存地址,把它改了,它就不会变成原样,你把它清理了,它就不会回来了。 用static的修饰的变量和方法,实际上是指定了这些变量和方法在内存中的"固定位置"-static