JVM

jvm

从问题引入

  • 什么是jvm?

  • jvm在java6 7 8 有着什么变化

  • jvm常见的调优参数有哪些?

  • 内存快照如何抓取?

  • 怎么分析dump文件?

  • 在java中 类加载器的认识

1 jvm存在的位置

image

2 jvm的体系结构

image

3 类加载器 类的初始化

我们要看的是这个类加载时候的一些个信息

image
3.1 加载器的种类
  • 跟加载器 BOOT

  • 扩展加载器 EXC

  • 应用程序加载器 APP

4 双亲委派机制

BOOT>EXC>APP

  • 在类请求类加载器加载的时候

  • 会向上进行委托直至boot

  • 如果能就加载,不能就返回上一级加载器加载

5 沙箱安全机制

个人理解就是限制了java代码运行的环境,只能在jvm中进行,而且不会干扰操作系统的运行

6 native 本地方法

比如线程的方法

  • 有native 修饰的方法,都是java 没有的功能 需要调用本地方法

  • 会进入本地方法栈执行

  • 调用的就是本地方法 JNI java native interface

  • 例如java 操作打印机

7 程序计数器

在单线程时候 这个东西是不需要的,因为即使没有,程序会按照指令执行下去,即使遇到分支跳转的情况,也会按照跳转到指定的指令处继续执行。

但是,现实的程序肯定都是多线程执行的,<mark style="box-sizing: border-box; background: rgba(229, 229, 229, 0); color: red; font-size: 20px;">jvm的多线程是通过cpu的时间片轮转来实现的</mark> 某个线程在执行的过程中可能会应为时间pain的耗尽而挂起,当他再次执行的时候呢,他就需要从挂起的地方开始执行,那么就是要通过程序计数器来记录字节码的执行位置,保证顺序的执行下去。

  • 具有线程的独立性

  • 占用的内存特别小

  • jvm中唯一不会内存溢出的一块

  • 在native时候 程序计数器值为空

  • 记录的事程序执行的字节码地址

8 方法区

  • 方法区是被所有的线程共享的

  • 所有字段、方法的字节码,还有一些各路的方法在这里(构造方法、接口代码)

  • 就是在类加载之后,会将一些类的信息存放在方法区里边

    <mark style="box-sizing: border-box; background: rgba(229, 229, 229, 0); color: red; font-size: 20px;">这个地方实在是不好理解</mark>

    引用:https://www.jianshu.com/p/59f98076b382

9 栈

运行的是程序执行时的方法,主管程序的运行,生命周期和线程同步。当线程结束,那么栈就会被释放,所以不会存在垃圾回收的问题。<mark style="box-sizing: border-box; background: rgba(229, 229, 229, 0); color: red; font-size: 20px;">是以线程为维度,堆是以进程为维度</mark>

  • 栈 先进后出 后进先出

  • 桶 新进先 后进后出 如队列

栈内存中:8种基本数据类型,对象的引用,实例的方法

image
  • 还有一个栈帧的概念,每一个方法在执行的时候都会有两个帧

    • 父帧

    • 子帧

10 堆

  • 一个jvm 中只有一个堆 进程级别

  • 当类加载器加载一个类之后 会将真实的对象放到堆中,那么在无线的创建对象中,会oom OutOfMemoryError

  • 分为

    • 新生区

    • 养老区

    • 永久区

image
  • GC 垃圾回收机制 主要存在于新生区+养老区

    • 轻GC

    • 重GC

​ 所有的对象创建后全部进入伊甸园,当满了之后 触发一次轻GC 活下来的进入幸存者区,当幸存者区也满了之后,意味着新生区满了,那么触发重GC,此时活下来的,流入老年区。

  • 永久区

    这个区域是常驻内存的,用来存放jdk自身携带的class对象,inteface元数据,存储java运行时的一些个环境。

    不存在垃圾回收,程序关闭 就释放

11 堆内存调优

  • -Xms20m -Xmx20m -XX:+PrintGCDetails 这个是打出gc描述信息

  • -Xms10m -Xmx20m -XX:+HeapDumpOnOutofMemory 报了内存溢出 那么久dump日志

工具 MAT Jprofiler
  • 分析dump文件 快速定位内存泄漏

  • 获得堆中的数据

  • 获得大的对象

    1 在idea中安装Jprofiler 插件 主要就是生成对应日志分析文件

    2 本地下载Jprofiler分析工具

    3 启动添加打出oom的dump文件命令

    4 将dump文件弄到Jprofiler 中分析

12 GC

作用域 在方法区和堆中进行

更确切的说是在:大部分时候在新生代 也会在幸存者区+老年区

GC逻辑 轻GC(Minor GC) 重GC(Full GC )
  • 新创建的对象都会进入Eden区 就是伊甸园区

  • 当Eden区满了之后 会进行轻GC 销毁没有继续引用的对象 部分不可销毁的对象进入幸存者1区 S0

  • 当触发了轻GC后 不可销毁的进入S0 此时 S1是空的

  • 当S0满了之后 会将还是没有销毁的对象放到S1里边(注意是全部),此时Eden触发轻GC 同样的存活下来对象也进入S1 S0空了

  • S0 和S1 会反复的复制存放(可以理解这个是剪切粘贴),但是当对象的反复存放超过15次 (-XX:MaxTenuringThreshold设置的值,默认是15) 那么会将对象放到老年代old

  • 当轻GC的时候,存回的对象大于S0 的大小 会直接进入老年代

  • 这就是著名的“停止-复制(Stop-and-copy)”清理法。


  • 当对象存活了足够长的时间,进入老年代,但是当老年代空间也不足的时候,触发重GC

  • 标记出存货对象,将所有存活对象向一端移动,保证内存连续

  • 可通过-XX:+HandlePromotionFailure额外设置 -----标记整理算法


  • 存放字节码、字符串常量池、静态变量、可持久化数据等

  • 重GC也会销毁老年代中的可销毁对象

算法

GC有哪些算法:

  • 标记清除法

  • 标记整理,

  • 引用计数器

  • 复制算法

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容