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文档,无论是思维脑图、学习笔记还是面试考点全整理好了,实际内容还有很多,就不一一展示,若你也需要这一套学习资料。

关注我的公众号:前程有光即可领取

【JVM专题】JVM从概述到调优图文详解,含思维脑图深度剖析!的更多相关文章

  1. JVM性能调优的6大步骤,及关键调优参数详解

    JVM性能调优方法和步骤1.监控GC的状态2.生成堆的dump文件3.分析dump文件4.分析结果,判断是否需要优化5.调整GC类型和内存分配6.不断分析和调整JVM调优参数参考 对JVM内存的系统级 ...

  2. 直通BAT必考题系列:JVM性能调优的6大步骤,及关键调优参数详解

    JVM内存调优 对JVM内存的系统级的调优主要的目的是减少GC的频率和Full GC的次数. 1.Full GC 会对整个堆进行整理,包括Young.Tenured和Perm.Full GC因为需要对 ...

  3. JVM 调优参数详解

    GC有两种类型:Scavenge GC 和Full GC 1.Scavenge GC 一般情况下,当新对象生成,并且在Eden申请空间失败时,就会触发Scavenge GC,堆的Eden区域进行GC, ...

  4. JVM性能调优监控工具详解

    现实企业级Java开发中,有时候我们会碰到下面这些问题: OutOfMemoryError,内存不足 内存泄露 线程死锁 锁争用(Lock Contention) Java进程消耗CPU过高 .... ...

  5. java应用性能调优之详解System的gc垃圾回收方法

    一.什么是System.gc()? System.gc()是用Java,C#和许多其他流行的高级编程语言提供的API.当它被调用时,它将尽最大努力从内存中清除垃圾(即未被引用的对象).名词解释:GC, ...

  6. MySQL性能调优——索引详解与索引的优化

    --索引优化,可以说是数据库相关优化.理解尤其是查询优化中最常用的优化手段之一.所以,只有深入索引的实现原理.存储方式.不同索引间区别,才能设计或使用最优的索引,最大幅度的提升查询效率! 一.BTre ...

  7. 面试题:MySQL性能调优——索引详解与索引的优化 没用

    ——索引优化,可以说是数据库相关优化.理解尤其是查询优化中最常用的优化手段之一.所以,只有深入索引的实现原理.存储方式.不同索引间区别,才能设计或使用最优的索引,最大幅度的提升查询效率! 一.BTre ...

  8. <JVM下篇:性能监控与调优篇>03-JVM监控及诊断工具-GUI篇

    笔记来源:尚硅谷JVM全套教程,百万播放,全网巅峰(宋红康详解java虚拟机) 同步更新:https://gitee.com/vectorx/NOTE_JVM https://codechina.cs ...

  9. <JVM下篇:性能监控与调优篇>01-概述篇-02-JVM监控及诊断工具-命令行篇

    笔记来源:尚硅谷JVM全套教程,百万播放,全网巅峰(宋红康详解java虚拟机) 同步更新:https://gitee.com/vectorx/NOTE_JVM https://codechina.cs ...

随机推荐

  1. 分布式监控系统之Zabbix主动、被动及web监控

    前文我们了解了zabbix的网络发现功能,以及结合action实现自动发现主机并将主机添加到zabbix hosts中,链接指定模板进行监控:回顾请参考https://www.cnblogs.com/ ...

  2. 深度分析:那些Java中你一定遇到过的问题,一次性帮你搞定!深度分析:那些Java中你一定遇到过的问题,一次性帮你搞定!

    1.java中==和equals和hashCode的区别 基本数据类型的比较的值相等.类的比较的内存的地址,即是否是同一个对象,在不覆盖equals的情况下,同比较内存地址,原实现也为 == ,如St ...

  3. 如何卸载MathType 7?

    作为好用的公式编辑器,一般情况下是不会将其从电脑上卸载的,但是当电脑负荷过多,导致电脑运行缓慢时,就需要考虑卸载一些软件,本节就来学习卸载MathType 7的方法. 具体操作步骤如下: 1.打开控制 ...

  4. 添加mysqli扩展

    find / -name phpize 进入mysqli目录下 ./configue -prefix=/usr/local/mysqli . make && make install ...

  5. MySQL制作具有千万条测试数据的测试库

    有时候需要制造一些测试的数据,以mysql官方给的测试库为基础,插入十万,百万或者千万条数据.利用一些函数和存储过程来完成. 官方给的测试库地址:https://github.com/datachar ...

  6. redis-cli 持久化,复制,哨兵,事务,流水线

    一.持久化: 快照文件RDB 保存"开始"创建新快照一刻的内存快照,创建过程的内存变化不会被记录 创建快照的办法有几种 1.客户端可以通过想Redis发送BGSAVE来创建一个快照 ...

  7. DNS、IP地址、子网掩码和默认网关

    一.DNS服务器 DNS是指:域名服务器(Domain Name Server).在Internet上域名与IP地址之间是一一对应的,域名虽然便于人们记忆,但机器之间只能互相认识IP地址,它们之间的转 ...

  8. 冲刺随笔——Day_Five

    这个作业属于哪个课程 软件工程 (福州大学至诚学院 - 计算机工程系) 这个作业要求在哪里 团队作业第五次--Alpha冲刺 这个作业的目标 团队进行Alpha冲刺 作业正文 正文 其他参考文献 无 ...

  9. python学习第五天 ----- 函数

    1. 内置函数 例如: print, round 2.自定义函数: 通过def来定义 def funcname(parameter_list): pass ⑴.参数parameter_list可以没有 ...

  10. Asp.NetCore之AutoMapper基础篇

    应用场景 现在由于前后端技术的分离,后端程序员在使用ORM框架开发后台API接口的时候,往往会将数据库的"数据模型"直接提供给前端.而大多数时候,可能这些数据并不能够满足前端展示的 ...