1.jvm之程序执行过程内存详解
栈
- 存放方法,方法压栈;
- 对象调用的方法会压入栈中,然后方法里会传入隐式参数 this ,表示当前对象的 引用地址,方法里如果要输出类的私有属性,就会默认在方法里的属性前面加上 this ,这就可以表示当前对象的 属性值了;
- 当一个方法执行完毕,就会出栈,直到所有方法执行,main 方法最后才会出栈
- 这些压栈的方法都是存放在内存当中;
- 压栈的方法有main方法,构造器(默认会传一个隐式参数this,表示当前对象),类中被调用的方法
堆
- 存放对象,每创建一个对象,都会产生对应的引用地址;
- 堆相当于是规范的具体实现,依照方法区里的类模板去创建对象;
- 通过构造方法压栈,去方法区找模板,然后在堆中创建对象
方法区
-
程序一开始,就会将类信息(属性,方法等)存放到方法区,相当于一个模板,之后再在堆中创建对象时,就直接从方法区这里拿模板(也就是引用地址)用,里面还有静态信息也会加载;
-
常量池中存放string字符串内容,然后也有对应的引用地址;
-
方法区相当于是一种规范,里面有类模板
总结:
- 同一类的每个对象有不同的成员变量存储空间;
- 同一类的每个对象共享该类的方法。
2. jvm之垃圾回收机制原理
-
java内存管理 很大程度上就是指 堆中对象的管理
-
没有被引用指向的 对象 就是垃圾(不可达对象), 需要被回收才行,降低内存消耗,提高程序运行速度
-
实现步骤:
1.发现垃圾
2.回收所有不可达对象的内存
3.jvm之垃圾回收算法介绍
3.1.垃圾回收相关算法:
3.1.1.引用计数法
优点:算法简单
缺点: “循环引用的无用对象” 无法识别
3.1.2.引用可达法(根搜索算法)
3.2.jvm之内存管理——分代垃圾回收机制
3.2.1.垃圾回收流程:
- 第一步:首先所有对象先进入到内存的 eden 区,成为 ”年轻代",然后在里面会有 对应的 Minor GC 监视对象,当 eden 区 已满后 ,Minor GC 就会将 eden 区全部清空, 如果里面还有 对象 被引用 ,就会将这些对象 放入到 ”年轻代“ 的另一个区 ,叫做
**Survivor1 区,**之后如果这也满了, Minor GC 就会又对 Survivor1 区 做一次 全部清空, 然后再将这些还被引用的对象放进 ”年轻代“ 的最后一个区 ”Survivor2 区 “。Survivor 2 满 ,就又去 Survivor 1 ;Survivor 1 满,就去 Survivor 2 ,如此循环交替清除无用(不可达或没有被引用)对象。
-
第二步:在”年轻代”经历N(默认 15)次垃圾回收后还存在的对象,就将该 “对象”放进 “年老代” 的 “Tenured” 区 进行管理。年老代中存放的都是一些生命周期比较长的对象。当年老代对象越来越多,就会启动 Major GC (清理 “年老代 ”) 和 Full GC(清理 “年轻代” 和 “年老代" ,全量回收,成本大,对系统性能影响大),全面清理年轻代区域和年老代区域。
-
第三步:如果此时的对象还没被清理, 就会存入 “永久代” ,这个地方用于存放静态文件,如java 类 、方法等。 持久代对垃圾回收没有显著的影响, JDK7以前是“方法区”的一种实现。JDK8 没有“永久代” ,使用 metaspace 元数据空间和堆替代。
3.2.2.垃圾回收总结:
堆内存划分 | 区域 | 垃圾回收器 |
---|---|---|
年轻代 | eden、Survivor1、Survivor2 | Minor GC |
年老代 | Tenured | Major GC |
永久代 | Full GC(对年轻代和年老代全面清理) |
4. jvm 调优
很大程度上是对 Full GC 进行调优
导致 Full GC :
- 年老代 (Tenured) 被写满
- 持久代 (Perm) 被写满
- System.gc()被显示调用
- 上一次GC之后Heap的各域分配策略动态变化
- 使用 System.gc() ,通知 JVM ,并不是运行垃圾回收器 。尽量少用, 会申请 Full GC , 成本高, 影响系统性能。它的作用是建议启动垃圾回收线程。
- finalize 方法, 是 Java 提供给程序员用来释放对象 或 资源的方法,但尽量少用
5.jvm之开发中容易造成内存泄露的操作——垃圾回收知识总结
-
内存泄漏原因:
1.创建大量无用对象
比如使用 String 类拼接字符串。
2.静态集合类的使用
像 HashMap 、Vector、List 等的使用最容易出现内存泄露,这些静态变量的生命周期和应用程序一致,所有的对象Object也不能被释放。
3.各种连接对象(IO 流对象、数据库连接对象、网络连接对象)未关闭
IO 流对象、数据库连接对象、网络连接对象等连接对象属于物理连接,和硬盘或者网络连接,不使用时一定要关闭。
4.监听器的使用
释放对象时, 没有删除相应的监听器