共计 2177 个字符,预计需要花费 6 分钟才能阅读完成。
JVM 概述
JVM 是一种用于计算机设备的标准,它是一个虚构的计算机的软件实现,简略的说,JVM 是运行 byte code 字节码程序的一个容器。
它有一个解释器组件,能够实现 JAVA 字节码和计算机操作系统之间的通信,java 程序只须要在 JVM 上一次编译,多出运行,因而 JAVA 具备跨平台性。
内存构造
- 办法区(常量池、动态变量、构造函数、类数据)
-
堆(对象、类实例、GC 的次要区域)
-
新生区(Minor GC、Full GC 清理无用数据)
* 伊甸园(对象创立)* 幸存 0 区 * 幸存 1 区
- 老年代(对象的申明周期到老年代完结)(Full GC)
- 永恒区(jdk 1.8 当前被元空间代替)(Major GC)
-
- 程序计数器(记录每个运行线程的内存地址)
- 虚拟机栈(每个办法创立都会创立一个栈,栈内的数据都是长期的)
- 本地办法栈
- 间接内存
堆中的 GC 回收过程
对象会在 Eden(伊甸园)调配创立,当 Eden(伊甸园)没有足够空间时将发动一次 Minor GC(垃圾清理),当 Eden 执行 Minor GC 后还不足以为对象调配空间,则大的对象间接进入老年代,能够用参数设置大对象间接进入老年代,防止频繁 Minor GC。如果对象在 Eden 创立,产生 Minor GC 后依然存活,且能被 Survivor 幸存去包容,年龄加 1,达到肯定年龄进入老年代,默认为 15。产生 Mrinor GC 之前先查看老年代最大可用间断空间是否大于新生代所有对象总空间,如果大于,阐明 Minor GC 平安;否则会判断是否被担保失败,如果担保失败了,判断老年代最大间断空间是否大于历次降职到老年代对象的均匀大小,如果大于则尝试 Minor GC,否则就执行 Full GC 进行对象回收,如果 Full GC 执行结束后,对象依然无奈被创立,则间接抛出内存溢出的异样(java.lang.OutOfMemoryError)。
如何扭转对象对象进入老年代的最大值?
通过批改 -XX:PretenureSizeThreshold 参数来设置进入老年代的对象年龄。这样也防止在 Eden(伊甸园)区和两个 Survivor 之间产生大量的内存复制。(默认值为 15)
GC 如何判断对象是否改被回收
垃圾收集的算法
都有那些垃圾回收器
内存透露(不再应用的对象的内存不能被 GC 回收)
内存透露的例子:
单例模式:
不正确应用单例模式是引起内存透露的一个常见问题,单例对象在初始化后将在 JVM 的整个生命周期中存在(以动态变量的形式)。如果单例对象持有内部的援用,那么这个对象将不能被 JVM 失常回收,导致内存透露。所以须要留神,尽量不要在单例中持有大对象。
各种连贯:
比方数据库连贯、socket 连贯、文件流等,除非其显式的调用其 close()办法将连贯敞开,否则是不会主动被垃圾 回收的。
动态汇合类:
咱们循环申请 Object 对象,并将所申请的对象放入一个 Vector 中。如果咱们仅仅开释援用自身,那么 Vector 依然援用该对象,所以这个对象对 GC 来说是不可回收的。
如果对象退出到 Vector 后,还必须从 Vector 中删除,最简略的办法就是将 Vector 对象设置为 null。
Static Vector v = new Vector(10); for (int i = 0; i < 100; i++) {Object o = new Object(); v.add(o); o = null; }
事件监听器:
AWT 的事件处理机制是一种委派式事件处理形式:一般组件 (事件源) 将整个事件处理委托给特定的对象(事件监听器);当该事件源产生指定的事件时,就告诉所委托的事件监听器,由事件监听器来解决这个事件。
比方罕用的监听器有 ActionListener、KeyListener、MouseListener、MouseMotionListener(专门解决鼠标静止事件的,比方鼠标的挪动和拖动)
如果在开释对象的时候没有记得删除这些监听器,会减少内存泄露的机会。
import java.awt.*; import java.awt.event.*; public class TestButton {public static void main(String args[]) {Frame f = new Frame("Test"); Button b = new Button("Press Me!"); b.addActionListener(new ButtonHandler()); /* 注册事件监听器 */ f.setLayout(new FlowLayout()); // 设置布局管理器 f.add(b); f.setSize(200,100); f.setVisible(true); } } // 实现接口 ActionListener 能力做事件 ActionEvent 的解决者 class ButtonHandler implements ActionListener {public void actionPerformed(ActionEvent e) {System.out.println("Action occurred"); } }
调优
JVM 思维导图
最初
这些 JVM 篇章曾经全副整顿成一套残缺且体系的 pdf 文档,无论是思维脑图、学习笔记还是面试考点全整顿好了,理论内容还有很多,就不一一展现,若你也须要这一套学习材料。
关注我的公众号:前程有光即可支付