JVM
jvm初学习
1双亲委派机制的工作过程:
如果用一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委托给父类加载器齐完成,每一层都是这样,只有当父类加载器反馈自己无法完成这个加载请求 时,(它的搜索范围没有找到这个类时).子加载器才会尝试自己去完成加载;
1优点:java中的类随着它的类加载器一起具备了一种带有优先级的层次关系;
2如果没有双亲委派机制:如果用户自己编写一个java.lang.Object
的类,并放在classpath,那那就出现了不同的Object类
,java类型体系中年最基础的行为也就无从保证,应用程序会混乱;
java在虚拟机的运行的过程:
java-javac__->java.class(java文件)-类加载器class loader
application class loader->Extension Class Loader->bootstrap class loader启动类加载器—到栈,方法区,堆
native
带native的关键字的方法说明java的作用范围达不到了,进入本地方法栈,调用本地方法接口,本地方法库,
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-32gQVYmf-1622688076095)(C:\Users\12479\AppData\Roaming\Typora\typora-user-images\image-20210602154616992.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B5126IHN-1622688076097)(C:\Users\12479\AppData\Roaming\Typora\typora-user-images\image-20210602151604302.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ftc0VNOY-1622688076098)(C:\Users\12479\AppData\Roaming\Typora\typora-user-images\image-20210602152515102.png)]
方法区
static,final,Class(模板),常量池都在方法区间.
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AWkviSVC-1622688076099)(C:\Users\12479\AppData\Roaming\Typora\typora-user-images\image-20210602153017956.png)]
栈
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cBwo8rIw-1622688076101)(C:\Users\12479\AppData\Roaming\Typora\typora-user-images\image-20210602185019016.png)]
堆
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sjuUe7eW-1622688076102)(C:\Users\12479\AppData\Roaming\Typora\typora-user-images\image-20210602210714860.png)]
据统计,大多数临时对象99%的都会死亡的
1新生区:PSYoungGen
-
伊甸园区间 eden
-
幸存取0 -from,
-
幸存区1- to
2养老区paroldgen;老年代
1.8之后,用元空间代替了老年代;
堆分区一般认为是有;Eden,from,to,老年区
3 永久存储区/metspace元空间(1.8之后),/非堆区/方法区;
逻辑上存在,实际不存在
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bvJEVYoP-1622688076103)(C:\Users\12479\AppData\Roaming\Typora\typora-user-images\image-20210602210813515.png)]
4堆默认最大的max为内存的1/4;total为内存的1/64;
// -Xms(1m):设置初始化内存分配大小 1/64
//-Xmx(8m) 设置最大分配内存,默认1/4
// -XX:+PrintGCDetails //打印GC垃圾回收
// -XX:+HeapDumpOnOutOfMemoryError
返回内存用的是Runtime()内这个的一些方法:
1M=1024*1024字节
5当堆出现OOM问题,排除问题
oom是error;捕获写的是Exception时,不会完全捕获,以及不会执行下面的,可以捕获(Error)
- 1先调整内存,扩展内存,
- 如果无效,在检查代码
- 2使用JProfiler工具;(elipse原来集成过的MAT):
- 分析内存泄露原因
- dump文件,分析:
GC
0当一个对象,默认经过了15次还没死,就能进入老年代了.
1只在堆和方法区进行GC
2轻GC— 新生代和偶尔的幸存区
重GC–(全局GC)
3GC的算法:
标记清除法,标记压缩,复制算法,引用计数器法;
1引用计数法;消耗内存
2复制算法:(年轻代主要用的是复制算法)
不适合于存活对象较多的场合 如老年代。
思想:将原有的内存空间分为两块,每次只使用其中的一块**,在垃圾回收时候,将正在使用的内存中的存活对象复制到为未使用的内存中**,清除正在使用的内存块中的所有对象,交换两个内存的角色,完成垃圾回收。
每次GC,都会将Eden活的对象移到幸存区中,一旦Eden被GC后,就是空的
复制算法完成后,第一块使用的那块内存完成清除,不管它存活还是未存活。都将它清理。
复制算法对空间有一定的浪费。只能使用一半的空间。
为了更好的利用复制算法 做一些扩展
- z自己总结的:谁空谁是to;
- 为了幸存区其中一个干净;
- 最佳使用场景:对象存活度较低的时候,新生区
3标记清除算法:对没有标记的对象,进行清楚
优点:不需要额外的空间
缺点:两次扫描,严重浪费时间**,会产生内存碎片**
4标记压缩(再优化):防止内存碎片产生,再次扫描.向一段移动对象多了一次移动成本
总结:
没有最好的算法,只有最合适的算法
- 分代收集算法
- 年轻代:
- 存活率低,
- 复制算法
老年代:
- 区域大,存活率高;
- 标记清除+ 标记压缩混合实现
记压缩(再优化):防止内存碎片产生,再次扫描.向一段移动对象多了一次移动成本
总结:
没有最好的算法,只有最合适的算法
- 分代收集算法
- 年轻代:
- 存活率低,
- 复制算法
老年代:
- 区域大,存活率高;
- 标记清除+ 标记压缩混合实现