JVM入门

1.请你谈谈jvm

2.什么是OOM,什么是栈溢出,怎么分析

3.jvm的常用调优参数有哪些

4.内存快照如何抓取,怎么分析Dumo文件

5.jvm中类加载器的理解

 

jvm的位置?

  在运行操作系统之上,

jvm的体系结构

  .java -->  Class File---->  类装载器(class loader)--->运行时数据区Runtime(方法区(method),本地方法栈(native),堆(heap),栈(stack),程序计数                   器)---->本地方法接口、本地方法库、执行引擎

  栈、本地方法栈、程序计算器 这三个地方不会有垃圾的  栈用完就弹出去了

  jvm调优就是在调整    堆和方法区,但是99%是堆

类加载器

  加载class文件,getClass   getClassLoader      只有一个类     对象有好几个

  虚拟机自带的加载器,启动类(根)加载器(Bootstrap ClassLoader)   扩展类加载器(Extensions ClassLoader)   

            应用程序加载器(Application ClassLoader)

双亲委派机制:C:\Users\Legion\IdeaProjects\JavaSE\Basic\src\com\songyue\shuangqinTest

  根加载器》扩展加载起》当前应用程序加载器

  1.类加载器收到加载请求

  2.将这个请求向上委托,一直到跟加载器

  3.根加载器检查是否可以加载,能加载就结束,不能加载抛出异常通知子加载器

  4.重复3

  优点:

    首先,保证了java核心库的安全性。如果你也写了一个java.lang.String类,那么JVM只会按照上面的顺序加载jdk自带的String类,而不是你写的String类。

    其次,还能保证同一个类不会被加载多次。

沙箱安全机制

Native

  带了native关键字的就说明java的作用范围达不到了,回去调用底层C语言的库,会进入本地方法栈、

  JNI本地方法接口  java  native interface  作用:扩展java类的使用,融合不同的语言为java所用,java诞生的时候C、C++横行,所以要有调用C、C++的程序

    在内存区域中专门开辟了一块区域,本地方法栈,登记native方法,最终执行的时候,加载本地方法库的方法 通过JNI

PC寄存器

方法区

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

栈:包括  8大基本类型+对象引用+实例的方法

  是一种数据结构,程序=数据结构+算法

  先进后出,后进先出:桶

  队列:先进先出(FIFO first input first output)

  为什么main先执行后结束,因为需要先把main压倒栈里面开始执行,然后调用其他方法,最后main结束,程序结束

  栈内存,主管程序的运行,生命周期和线程同步,线程结束,栈内存也就释放了,对于栈来说不存在垃圾回收,一旦线程结束,程序也就结束了

  栈+堆+方法区的交互关系  

三种jvm

  Sun公司HotSpot:咱们自己用的,另外的不重要

堆:gc垃圾回收主要在伊甸园和养老区,内存满了OOM,堆内存不够

  Heap,一个jvm只有一个堆内存,堆内存大小是可以调节的

  类加载器读取了类文件后,会把什么东西放到堆中:  类、方法、常量、变量、保存我们所有引用类型的真是对象

  堆中还要细分为三个区域

   Eden 新生区:伊甸园   里面有幸存0区,幸存1区   幸存区 分为from to   谁空谁是to

    Old   养老区

   Perm 永久区:JDK8以后叫元空间

新生区

  一个类,诞生成长甚至死亡

  伊甸园:所有的对象都是在这里new出来的

  幸存区(0,1)

老年区

永久区:这个区域常驻内存,用来存放JDK自身携带的Class对象,interface元数据,存储的是java运行时的一些环境或者类信息,这个区域不存在垃圾回收

    关闭VM虚拟机就会释放这个区域的内存

  jdk1.6之前:永久代,常量池在方法区

   jdk1.7:   永久代但是慢慢退化了,去永久代常量池在堆中

  jdk1.8之后:无永久代,常量池在元空间  元空间逻辑上存在,物理上不存在

堆内存调优

  oom时的解决办法:1.调整堆内存空间如果还有问题,就看代码有没有死循环垃圾代码

    能够看到第几行代码出错  是最快的,内存快照分析工具Jprofiler

    Jprofiler作用:分析Dump内存文件快速定位内存泄露,获得堆中的数据,获得大的对象

  设置Dump:-Xms 设置初始化内存分配大小默认   1/644 , -Xmx设置最大分配内存默认 1/4   ,-XX:+PrintGCDetails  GC清理的垃圾信息

        -XX:+HeapDumpOnOutOfMemoryError  打印OOM

GC

  轻GC针对新生代、幸存区

  重GC(full)

  jvm内存模型和分区~详细到每个区放什么

  堆里面的分区有哪些 ,Eden from to 老年区说说他们的特点

  GC的算法有哪些,标记清除法,标记压缩,复制算法,引用计数器怎么用的?

  轻GC和重GC分别在什么时候发生?

  复制算法就是把所有的东西在GC的时候都放在 幸存区中的某一个里面(比如Eden里面的和幸存区from里面的 ),所以没有内存的碎片,不过浪费空间

      最佳使用条件是就是对幸存活度较低也就是新生区

  标记清除算法:GC时标记,清除时清除没用的

    缺点:两次扫描,浪费时间,会产生内存碎片

    优点:不需要额外的空间

  标记压缩:防止内存碎片

 

  内存效率:复制算法》标记清除算法》标记压缩算法

  内存整齐度:复制算法=标记压缩算法》标记清楚算法

  内存利用率:标记压缩算法=标记清除算法》复制算法

没有最好的算法,只有最合适的  GC分代收集算法

  年轻代:存活率低--》复制算法

  老年代 :存活率高--》标价清除+标记压缩

    每次GC都会将Eden中活的对象移到幸存区中,每次GC后Eden都是空的,当一个对象经历了15次GC都没有死,就会进入养老区

JMM:JAVA Memory Model(java内存模型)

posted @   皇天不负有心人  阅读(43)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示