0
点赞
收藏
分享

微信扫一扫

JVM探究

冶炼厂小练 2022-03-20 阅读 57

目录

常见面试题

整体内容:

内容答案:

1.JVM位置

2.JVM体系结构

 3.内加载器

 4.双亲委派机制

 5.沙箱安全机制

6.Native关键字

7.PC寄存器

8.方法区

9.栈 

 10.三种JVM

11.堆 

 12.新生区,老年区

13.永久区:

14.堆内存调优:

15.GC常用算法

16.JMM

17.总结 


常见面试题

  • 请你谈谈对jvm的理解?java8虚拟机和之前的变化跟新?
  • 什么是OOM,什么是栈溢出StackOverFlowError?怎么分析?
  • JVM常见调优参数有哪些?
  • 内存快照如何抓取,怎么分析Dump文件?知道吗?
  • 谈谈JVM中类加载器你的认识?

整体内容:

  1. JVM位置  
  2. JVM体系结构
  3. 类加载器
  4. 双亲委派机制
  5. 沙箱安全机制
  6. Native
  7. PC寄存器
  8. 方法区
  9. 三种JVM
  10. 新生区,老年区
  11. 永久区 
  12. 堆内存调优 
  13. GC  常用算法
  14. JMM
  15. 总结

内容答案:

1.JVM位置

2.JVM体系结构

jvm加载是先从电脑的磁盘中找到该java文件,加载成class文件然后在进行类加载器,去运行到运行数据区,jvm运行时数据区有:方法区,java栈,本地方法栈,堆,程序计数器,等等.....

 

而在,java栈,本地方法区,和程序计数器中一定不会有垃圾,一般的jvm调优都是在堆中进行垃圾回收调优的. 

 

 3.内加载器

作用:加载Class文件

  1. 虚拟机自带的加载器
  2. 启动类(根)加载器
  3. 扩展类加载器
  4. 应用程序加载器(类加载器)

 4.双亲委派机制

双亲委派机制有三层如:

  • Bootstrap classLoader:根加载器,主要负责加载核心的类库(java.lang.*等),构造ExtClassLoader和APPClassLoader。
  • ExtClassLoader:扩展类加载器,主要负责加载jre/lib/ext目录下的一些扩展的jar。
  • AppClassLoader:应用程序加载器主要负责加载应用程序的主函数类

当一个对象被加载的时候:

  1. 类加载器会受到加载的请求
  2. 这个请求向上委托父类加载器去完成,一直向上委托,直到启动类加载器
  3. 启动加载器检查是否能够加载当前这个类,能加载就结束使用当前的类加载器,否则抛出异常通知子加载器进行加载,

将会进行重复3次的步骤,此外根加载器是获取不到的因为根加载器使用c/c++写的:

package com.tang.Servlet.test;

public class Car {
    public static void main(String[] args) {
        ClassLoader classLoader = Car.class.getClassLoader();
        System.out.println(classLoader);//输出应用类加载器
        System.out.println(classLoader.getParent());//输出扩展类加载器(平台类加载器)
        System.out.println(classLoader.getParent().getParent());//获取不到跟加载器
    }
}

输出:

jdk.internal.loader.ClassLoaders$AppClassLoader@2437c6dc
jdk.internal.loader.ClassLoaders$PlatformClassLoader@4c203ea1
null

小历史:创建java的时候创作者是想要抛出c++的指针和内存管理这些繁琐的过程,进行创建java这门语言,所以现在这些繁琐的内存管理,JVM已经帮我们做好了,如此java也被戏称为C++--.

 5.沙箱安全机制

 作用:早期用来保证对代码的有效隔离,防止对本地系统造成破坏,调用他人编写的代码,具体可查看:

java中的安全模型(沙箱机制)_改变ing的博客-CSDN博客_沙箱安全机制

6.Native关键字

7.PC寄存器

8.方法区

9.栈 

栈是一种数据结构

  • 栈:先进后出
  • 队列:后进先出 

例如:喝多了吐就是栈,吃多了拉就是队列.

栈:栈内存主管程序的运行,生命周期于线程同步.

线程结束栈内存也就释放,对于栈来说不存在,垃圾回收问题,一旦线程结束栈也跟着结束了.

栈中存放:8大基本数据类型+对象引用+实例的方法 

 

栈运行原理:栈帧

如果栈满了则会抛出StackOverflowError

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

 10.三种JVM

通过Dos命令java -version 查看当前jvm的版本信息如:

 

  • Sun公司 HotSpot  Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.12+8-LTS-237, mixed mode)
  • BEA公司 JRocket
  • IBM公司 j9 vm

我们都是通过HotSpot迅即进行学习的

11.堆 

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

类加载器读取了类文件之后,一般会把什么东西放在堆中?类,方法,常量,变量,保存我们所有引用类型真实对象;

堆内存中还要细分为三个区域:

  • 新生区(伊甸园区) Young/New
  • 养老区   old
  • 永久区   Perm

 12.新生区,老年区

新生区:

  • 类:诞生和成长的地方,甚至死亡  .
  • 伊甸园区,所有的对象都是在伊甸园区new出来的!
  • 幸存者区(0,1)

 

 真理:经过研究,99%的对象都是临时对象!

老年区: 

13.永久区:

 元空间:逻辑上存在,物理上不存在.

public class test {
    public static void main(String[] args) {
        //返回虚拟机试图使用的最大内存
        long max = Runtime.getRuntime().maxMemory();    //字节为单位
        //返回虚拟机运行时的总内存
        long total = Runtime.getRuntime().totalMemory();
        System.out.println("max="+max+"字节\t"+(double)(max/1024/1024)+"MB");
        System.out.println("total="+total+"字节\t"+(double)(total/1024/1024)+"MB");

        //默认情况下堆内存分配总内存是:电脑的1/4,而初始化的内存是1/64
        //-Xms1024m -Xms1024m -XX:+PrintGCDetails
        //遇到OOM解决方案:
        //1.尝试扩大内存空间查看结果
        //2.分析内存查看那个地方出现了问题(专业工具)
    }
}

在一个项目中突然出现了OOM故障该如何排除~研究为什么出错~

  • 能够看到代码第几行出错:内存快照分析工具,MAT,Jprofiler
  • Dubug一行一行分析代码

MAT,Jprofiler作用:

  •  分析Dump内存文件,快速定位内存泄漏
  • 获得堆中的数据
  • 获得大的对象

14.堆内存调优:

可以进行堆内存的大小初始化调整. 

package Tang;

import java.util.ArrayList;

//-Xms1m -Xmx8m -XX:+HeapDumpOnOutOfMemoryError
public class test3 {
    byte[] a= new byte[1*1024*1024];//表示1m(1兆)

    public static void main(String[] args) {
        //-Xms 初始化内存大小,默认电脑内存的1/64
        //-Xmx 最大分配内存,默认电脑内存的1/4
        //-XX:+PrintGCDetails 打印GC信息
        //-XX:+HeapDumpOnOutOfMemoryError  如果是内存不足错误就打印出堆的Dump文件

        ArrayList<Object> test3 = new ArrayList<>();
        int temp=0;
        try {
            while (true){
                test3.add(new test3());//问题所在
                temp++;
            }
        } catch (OutOfMemoryError e) {
            System.out.println("增加次数"+temp);
            e.printStackTrace();
        }
    }
}

15.GC常用算法

GC:是垃圾回收的守护线程,可通过System.gc()手动实现调用.

GC作用域是在方法区和堆里,因为只有这两个地方才会产生垃圾对象

 

 JVM在进行GC(垃圾回收)时,并不是对这三个区域,统一回收,大部分时候回收都是新生代~

  • 新生代
  • 幸存区(from to)
  • 老年区

 GC题目:

  • JVM内存和分区~详细到每个区放什么~
  • 堆里面的分区有哪些~Eden,from,to,老年区,说说他们的特点~
  • GC的算法有哪些?标记清除法,标记压缩,复制算法,引用计数器怎么用的?
  • 轻GC和重GC分别在什么时候发生?

 引用计数法:

 

 复制算法:

  •  好处:没有内存碎片
  •  坏处:浪费了一个幸存区的空间,to区永远是空的.. 

 复制算法最佳使用场景:对象存活较低的时候

标记压缩清除算法: 

标记清除:

  • 优点: 弥补了复制算法的不足,未浪费空间.
  • 缺点:两次扫描,严重的浪费了时间,会产生内存碎片。

 标记压缩清除算法优化:

 

  • 优点: 不在产生实现碎片,使空间连续,弥补了复制算法的不足.
  • 缺点:三次扫描,严重的浪费了时间。

16.JMM

1.什么是JMM?

        Java Memory Model(java内存模型)简称JMM

2.他是干嘛的?

        作用:缓存一致性协议,用于定义数据读写规则!

17.总结 

思考:难道没有最好的算法吗?

答案:没有,没有最好的算法,只有合适的算法.-->GC是分代收集算法

文章大部分参考于:【狂神说Java】JVM快速入门篇_哔哩哔哩_bilibili 

举报

相关推荐

0 条评论