虚拟机垃圾收集机制探寻与代码优化

Java开发有个很基础的问题,虽然我们平时接触的不多,但是了解它却成为Java开发的必备基础——这就是JVM。在C++中我们需要手动申请内存然后释放内存,否则就会出现对象已经不再使用内存却仍被占用的情况。在Java中JVM内置了垃圾回收的机制,帮助开发者承担对象的创建和释放的工作,极大的减轻了开发的负担。

1. JVM内存模型回顾

在这里插入图片描述
这几个存储区最主要的就是栈区和堆区和方法区,那么什么是栈什么是堆什么是方法区呢?

栈区
里面存放的是基本的数据类型和引用,线程私有,生命周期与线程相同。每个方法执行的时候都会创建一个栈帧(stack frame)用于存放
局部变量表、操作栈、动态链接、方法出口。

堆区
里面则是存放各种对象实例的,也叫做java堆、GC堆是java虚拟机所管理的内存中最大的一块内存区域,也是被各个线程共享的内存区域,在JVM启动时创建。该内存区域存放了对象实例及数组(所有new的对象)。
由于现在收集器都是采用分代收集算法(标记清除,分段赋值法,标记整理法,分代收集法),堆被划分为新生代和老年代。新生代(伊甸园,生存区(FROM,To))主要存储新创建的对象和尚未进入老年代的对象。老年代存储经过多次新生代GC(Minor GC)任然存活的对象。

方法区
类型信息、字段信息、方法信息、其他信息。

2. 伟大的环卫工人

如何找到垃圾?

(1)引用计数法

在这里插入图片描述

(2)根搜索算法(GC Root)

在这里插入图片描述

4. 环卫工人也要与时俱进

(1)Mark-Sweep标记-清除算法

在这里插入图片描述

(2)Copying分段复制算法

在这里插入图片描述

(3)Mark-Compact标记-整理算法

在这里插入图片描述

(4)Generational Collection 分代收集

在这里插入图片描述

在这里插入图片描述

5. 如何编写高效的Java代码

  1. 尽量不要在循环中: 使用try…catch、new 对象;
  2. 把频繁使用的短命对象缓存起来;
  3. 尽可能使用栈内变量(方法内局部变量)
  4. 不要用异常来控制代码流程
  5. 用线程池、连接池,不要自己创建
  6. 学会读Java核心API源代码
  7. Java进阶的好书:《Effecitve Java》

8. 内存泄露与内存溢出,用jvisualvm剖析

(1)内存泄漏

在这里插入图片描述
在这里插入图片描述

(2)内存溢出

因为没有解决内存泄漏的问题才会出现内存溢出

9. 实操:手把手教你干掉健壮如牛的JVM

  1. 调整堆内存大小:-Xms256M –Xmx512M
  2. 调整栈内存大小:-Xss2048k
  3. 调整方法区大小:-XX:MetaspaceSize=64M -XX:MaxMetaspaceSize=128M
  4. 调整方法区大小:-XX:PermSize=64M –XX:MaxPermSize=128M Java 7及以前适用

おすすめ

転載: blog.csdn.net/qq_42862247/article/details/87861734