java的内存处理流程:
第一步:JVM申请内存
第二步:初始化运行时数据区
第三步:类加载
第四步:执行方法
第五步:创建对象
GC概念
Java中GC会自动回收堆中的垃圾
可以主动触发垃圾回收:System.gc(),非常影响性能,不推荐
内存可视化工具HSDB
HSDB,jdk下的一个检测jvm运行时的可视化工具。
可以查看堆信息,如查看堆中对象的地址
也可以查看栈信息,如查看局部变量表.
JVM对栈的优化技术:
当形参(局部变量表)和实参(操作数栈)进行值传递时,这个实参和形参都共用一个内存地址,节约空间。
栈和堆的内存区别:
存储内容
栈:基本数据类型以及对象引用。线程执行完毕就释放掉
堆:存储对象。(一个类被new出来,他的成员变量如果是基础类型还是在堆??????)
线程关系
对于栈,里面的所有元素都是私有的
对于栈,里面的元素都是共享的
空间大小
栈是很小的(一个虚拟机栈,也就是一个线程分配1m,仔细思考一个栈帧分配1m它配么?)。
堆是比较大的,存放了所有的对象。循环创建对象将非常庞大
常量池与字符串
Class(静态)常量池
Class里面的东西(接口,方法,版本,字面量
字面量
什么是字面量?这东西一开始先保存在方法区,然后再根据String或者int分配到栈或者方法区么?
String a =”123”; String的字面量
Int a =123; int的字面量
符号引用 ????
在Person类中引用Tools类
编译的时候,tools真实内存地址
Org.king.Tools ---符号引用
类加载的时候---符号引用---真实引用
运行常量池
直接引用放在运行时常量池。(根本没明白!!!!)JDK1.7以后可以放在堆里。但逻辑上还是在方法区(完全不懂)
字符串常量池
不知道是属于运行常量池还是独立出来,但这个东西就是为了存放String类型的数据的。
String类是final。Value也是final。不能被重写,数据不能被修改,所以String都存放在字符串常量池。为什么这么设计?
- 安全
- Hash唯一 hashmap key-value