内存管理机制
1 运行时数据区域:
1.1程序计数器:当前程序所执行的字节码的行号暗示器。java多线程会有多个计数器独立存储,称为 线程私有内存。
1.2 Java虚拟机栈(线程私有):局部变量表存放编译期间可知的基本数据类型(boolean byte char short int float long double)、对象引用和returnaddress类型。64位长的long double占2个局部变量空间,其余的占一个。为虚拟机执行的java方法服务;
1.3 本地方法栈 为虚拟机使用到的native方法服务;
1.4 java堆:是内存中最大的一块,存放对象实例、数组,GC堆;
1.5 方法区:与java堆一样,是各个线程共同的内存区间,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码数据。
1.6运行时常量池 方法区的一部分。class文件中除了有类的版本、字段、方法、接口等,还有常量池。
1.7 直接内存:NIO类 基于通道和缓存区的IO方式 native函数库分配堆外内存。
2 hotpot虚拟机对象:
2.1 分配内存创建对象,多线程。
2.2 对象内存布局:对象头(存储对象自身运行时数据,类型指针),实例数据,对齐填充(占位符)。
2.3 对象的访问定位:句柄访问,java堆划分一块内存作为句柄池,reference中存储的就是对象的句柄地址,存储稳定;直接指针访问,reference存储的直接就是对象地址,访问快。
垃圾收集和内存分配
1.对象已死:
1.1 引用计数法:给对象添加一个引用计数器,有引用计数器加1,引用失效计数器减1,计数器为0 则不可用。不能解决对象的相互循环引用。
1.2 可达性分析算法(java C#): 通过GC Roots对象为起点向下搜索构成引用链,当对象到达GC Root没有引用链 则不可用。
GCRoots对象包括:虚拟机栈中引用对象,方法区中类静态属性引用对象,方法区常量引用对象,本地方法栈中Native引用对象。
1.3 方法区垃圾回收,永久带常量池。
2 垃圾收集算法:
2.1 标记清除算法,效率问题,空间问题;
2.2 复制算法,不适用对象多 老年代;
2.3标记整理算法;
2.4 分代收集算法:把Java堆分为新生代和老年代,前者用复制法,后者用标记清理或标记整理算法。
3 hotspot算法,垃圾收集器;
4 内存分配与回收策略:
4.1 对象优先在Eden分配;
4.2 大对象直接进入老年代,需要大量连续内存空间的java对象,长串的数组
4.3 长期存活的对象将进入老年代,每个对象有对象计数器,对象升老年代阈值可以设置;
4.4动态对象年龄判定,survivor中相同年龄的对象和大于空间一半,年龄大于该值得对象进入老年代;
4.5 空间分配担保
虚拟机工具
1 JDK命令行
1.1 jps