JVM

程序 = 数据结构 + 算法

1.JVM体系结构

JVM是在操作系统上面的,使用c/c++写的,属于JRE
JVM组成:方法区(Method Area),Java栈(Java stack)、本地方法栈(Native Method)、堆(Heap)、程序计数器
JVM调优99%是在方法区和堆,其中的99%是在堆中

栈一般存放引用,放对象在堆中的地址
堆一般存放new的对象和数组
在这里插入图片描述

类的加载过程

在这里插入图片描述

类是模板(只有1个),对象是具体的(很多个)

2.双亲委派机制,主要是保证安全

类加载器:App(应用程序加载器)–>Ext(扩展加载器)–>Boot(根加载器)
双亲委派(先向上委派,再向下委派;也就是请求向上,加载向下):

  1. 类加载器收到类加载的请求,类加载器保证线程安全
  2. 将请求向上委派给父类加载器,一直向上委派,直到跟加载器
  3. 启动加载器检查是否能加载当前这个类,能加载就结束,使用当前的加载器,不行就向下通知子加载器加载
  4. 重复3,直到在App(应用程序加载器)中查找,
  5. 如果没找到就报异常ClassNotFound
  • 可以想象啃老族,父母没有才会自己动手
    如果java的同包同类名的类(String):实例化会怎么样
    报异常:找不到main方法,因为双亲委派机制(在root根加载器就查找到了这个类)

为啥程序中获取不到跟加载器的信息

  • 因为java底层是用C、C++写的,java调用不到

3.沙箱安全机制

Java安全模型的核心,限制程序运行的环境,将Java代码限定在JVM特定的运行环境中,严格限制代码对本地资源访问(主要限制系统资源访问
双亲委派机制实现沙箱安全机制

4.Native和方法区

  • 带Native关键字的,说明Java作用范围达不到了,会去调用底层C语言的库,进入本地方法栈,调用本地方法的本地接口(JNI)
  • 方法区:被所有线程共享,所有定义的方法的信息都保存在该区域,此区域属于共享区域

静态变量、常量、类信息(构造方法、接口定义)、运行时的常量池存在方法区中,但是实例变量存在堆内存中,和方法区无关

JNI:扩展Java的使用,融合不同的编程语言为Java所用(本地方法栈登记native方法,执行的时候通过这个调用本地方法接口JNI)

Java的本质是值传递

5.栈和队列

  • 栈:先进后出(main方法):喝多了吐
    • 主管程序的运行,生命周期和线程同步;线程结束,栈内存释放,不存在垃圾回收机制(线程级)
    • 存放:8大基本类型+对象引用+实例的方法
  • 队列:先进先出(FIFO):吃多了拉
  • 栈溢出:就是两个方法互相调用对方,一直往栈里面压,导致栈被压满了

6.堆

Heap,一个JVM只有一个堆,堆内存可以调节 (调优)
存:类、方法、常量、变量、引用类型的真实对象

分区
在这里插入图片描述

  • GC垃圾回收主要是在伊甸园区和养老区(jdk8以后永久存储区叫元空间
    在这里插入图片描述

通过代码获取堆空间大小

发现总空间=eden+old,没有meatspace的空间,即逻辑上元空间存在堆中,但物理上不存在堆中
在这里插入图片描述

GC调优主要是堆:
VM options:-Xms8m -Xmx8m -XX:+PrintGCDetails
PrintGCDetails:印GC垃圾回收信息
Xms:设置初始化内存分配大小,1/64 对应于Xmax
Xmax:设置最大分配内存:默认1/4 对应电脑内存

7、GC垃圾回收

  • 新生区:伊甸园区(Eden)、幸存0区(from)、幸存1区(to),from和to会相互转化,谁是空的谁就是to

当一个对象经过15(可设置)次GC都还没死,就会进入养老区

  • 养老区
  • 永久区(JDK8以后改成了元空间):常驻内存,用来存放JDK自身携带的Class对象,方法区,Interface元数据以及Java运行时的一些环境和类对象,不存在垃圾回收,关闭虚拟机释放内存

GC垃圾回收,主要是在伊甸园区和养老区

内存分析插件

内存快照分析工具:能看到第几行代码出错(Jprofiler,eclipse的MAT)

  • 分析Dump内存文件,快速定位内存泄露

Xms1m -Xmax8m -XX:+HeapDumpOnOutOfMemoryError

  • 打印OOM栈溢出的信息,生成profile文件
  • 获得堆中的数据及大的对象

7.题目

  • JVM的内存模型和分区~详细到每个区放什么?
  • 堆的分区:Eden、from、to、老年区,特点?
  • GC的算法?
    • 引用计数器:给每个对象都配对一个计数器,引用就+1,为0就销毁,会造成很大消耗
    • 复制算法:主要用在新生区(from和to),如果from和to都有对象,就可以把from的对象复制到to中,然后from变成to(to必须一直为空,谁空谁是to);默认值:当一个对象经历了15次gc还没死,就进入养老区
      • 好处:没有内存碎片
      • 坏处:浪费了一半内存(多了一半是to区)
      • 复制算法使用场景:对象存活率较低的区域
    • 标记清除法:对有引用的对象标记,对没有标记的对象清除
      • 优点:不需要额外的空间
      • 缺点:两次扫描,浪费时间,会产生内存碎片
    • 标记压缩:再次扫描,将存活的对象移动到一端,解决标记清除的内存碎片问题 (多了移动的成本) (再优化:多进行几次GC,再进行压缩)
没有最优的方案,永远只是时间或空间的权衡。

现在又不缺空间,所以优先复制算法

GC:分代收集算法(年轻代:复制算法,老年代:标记清除算法+压缩混合)

  • 轻GC(新生和养老区)和重GC(**和永久区)分别发生的时候?
学习新东西方法

比如说JMM

    1. 什么是JMM?
    1. 它是干什么的?
    1. 它该如何学习?
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值