Java中的内存分配机制
(分配和释放问题)
1. 与C++的对比:
(1) C++:被分配的对象,不使用后,需要人工手动释放(使用析构函数)
(2) Java:垃圾回收gc动态回收(若收不了:内存泄露-> 人工置null)
2. Java中的8种数据类型:
int、char、short、long、byte、float、double、boolean
3. Java内存区域:
(1) 静态存储区域:全局变量和static变量(编译时就分配好,整个生命周期均存在)
(2) 栈:局部变量和对象的引用变量;(速度快,小,可共享,但缺乏灵活性)
(3) 堆:new创建的对象以及实例变量;(动态分配)
eg: 针对包装类(interger、string)
String str = “abc”; //存储在栈中
String str = new String(“abc”);
// str对象引用储存在栈中,而对象数据abc存储在堆;
过程:先在栈中查找有没有存放abc的地址,有(直接查找对象),没有 (创建新的对象str,指向该地址)
4. Java内存分配机制:
(1) Java程序执行过程:
(2) 执行过程
① Java源代码文件(.java)->(java编译器)-> 字节码文件(.class);
② JVM:-> -> 类加载器 ->->引擎执行 (执行过程中,JVM内存来存储)
③ 类加载机制:
1) 加载:加载类的二进制文件,获取类的二进制流(将字节流的静态存储结构转换为方法区的数据结构); 在java堆中生成java.lang.Class对象(入口)。
2) 验证:确保字节流符合虚拟机的要求(文件格式、元数据、字节码、符号引用)。
3) 准备:为变量分配内存并设置初始值。
4) 解析:将常量池中的符号引用转化为直接引用的过程。
5) 初始化:执行类构造器等。
(3) Java垃圾回收机制(GC)
① GC判断方法:引用计数(引用一次+1,失效-1,为0则回收)
② GC六大问题:
1) GC定义:动态存储的管理技术,自动释放不再引用的对象;
2) 特点:自动进行;
3) 运行时期:CPU空闲或空间不足;
4) 符合回收条件:该对象无任何线程访问时;(空引用)
③ 程序健壮的手段:(避免内存泄漏)
1) 释放无用对象的引用:null;
2) 定义字符串尽量使用
String a = “abc”;而非string z = new string(“abc”);
3) 若有大量字符串:(尽量使用StringBuffer,而非String)
4) 尽量少使用static变量;(不会回收)
5) 尽量避免在类的构造函数中创建和初始化大量对象,防止浪费;
6) 尽量少用finalize函数,finalize()会加大GC的工作量;
7) 不要过滥使用hash表;
8) 忌讳在循环中创建对象。
(4) java中的引用:
① 强引用:(创建一个对象并赋值)(不会回收)
Person person = new Person(“sunny”);
② 软引用:(通过SoftReference类实现)(资源紧张会回收)
SoftReference p = new SoftReference(new Person(“Rain”));
③ 弱引用:(通过WeakReference类实现)(均会回收)
WeakReference p = new WeakReference(new Person(“Rain”));
④ 虚引用:(不能单独使用,主要是用于追踪对象被垃圾回收的状态)
5. 内存相关问题:
① 内存泄漏:分配出去的内存未回收,资源浪费;
② 内存溢出:内存不足;
③ 符号引用:
④ 直接引用:
⑤ ...