一篇了解JVM

一、

                                            Java应用程序

                                            JVM

                                           系统API

  1. JVM
  2. JVM本身是一个规范,规定了不同的厂商要实现的基本功能,比如对class文件的结构校验规则。
  3. (HotSpot  JVM):Oracle公司提供
  • JVM运行流程:

    .class文件怎么被加载并运行:
    1.加载class
    2.类对象(Class)存放在方法区,以便以后new对象的时候可以从这个类对象模板来创建真实的对象
    3.new出来的对象都是在堆里
    4.Java虚拟机栈,每个线程都会分配一个栈,存的是方法调用
    5.本地方法栈,保存的是本地方法调用层级
    6.程序计数器,保存的是当前代码执行的行号

二、问题

1.JVM运行时数据区包括哪些区域?
(1) 内存共有的

        方法区:jdk8 元空间、jdk7 永久的、
        堆:JVM 参数设置 -Xms10m 最小启动内存是针对堆的,-Xmx10m 最大运行内存也是针对堆 的。(ms 是 memory start 简称,mx 是 memory max 的简称)

一般最大和最小都设置成一样的。当堆内存设置的比较小时,可能会出现OOM错误,如果出现此问题可以将之设置的大一点。

(2)内存私有的 

        Java 虚拟机栈:每一个方法都是一个栈帧(入站的元素)栈容量只需要由-Xss参数来设置

如果压入元素过多,会报出StackOverFlow错误


        本地方法栈
        程序计数器        

2.类加载的过程:

(1)加载:

在当前classpath下找到所有.class文件,读取到内存中。

(2)验证:

 .class文件的规范:

验证是连接阶段的第一步,这一阶段的目的是确保Class文件的字节 流中包含的信息符合《Java虚拟机 规范》的全部约束要求,保证这些信 息被当作代码运行后不会危害虚拟机自身的安全。

验证选项: 文件格式验证 字节码验证 符号引用验证...

(3)准备:准备阶段是正式为类中定义的变量(即静态变量,被static修饰的变量)分配内存并设置类变量初始值 的阶段。

假如此时有这样一行代码:

public static int value = 123;

它是初始化 value 的 int 值为 0,而非 123

(4)解析:解析阶段是 Java 虚拟机将常量池内的符号引用替换为直接引用的过程,也就是初始化常量的过程。

(5)初始化:初始化阶段,Java 虚拟机真正开始执行类中编写的 Java 程序代码,将主导权移交给应用程序。初始化 阶段就是执行类构造器方法的过程,初始化完成之后,一个对象就会被创建出来。

3.双亲委派模型:一个类再加载的时候可能使用不同的类加载器

BootStrap :启动加载器

ExtClassLoader : 扩展加载器

AppClassLoader:应用程序类加载器

自定义加载器:编程人员指定的特殊目录

 问题:

1.说说Java中有哪些类加载器

BootStrap、ExtClassLoader、AppClassLoader、自定义加载器。

当创建一个类时,先从applicationClassLoader开始向上转发,一直到BooStrapClassLoader

BootStrapClassLoader在自己的家在路径中查找有没有这个类,有则加载,没有则向下转发,

转发到ExtClassLoader,在自己路径中加载,有则加载,没有则向下转发至AppClassLoader,然后再查找。

2.垃圾回收:

我们常说的垃圾回收主要是在堆里面,(栈内存在线程销毁时自动回收)

垃圾回收主要回收的是死亡的对象,释放所占的内存

那么如何去标识一个对象是否死亡?
(1)引用计数法:如果一个对象被引用,那么引用次数就+1,当引用次数为0时那么就意味死亡 

(会有内存泄露的风险)

(2)可达性分析:JVM实际采用的方法

在Java语言中,可作为GC Roots的对象包含下面几种:

  •  虚拟机栈(栈帧中的本地变量表)中引用的对象;
  •  方法区中类静态属性引用的对象;
  •  方法区中常量引用的对象;
  •  本地方法栈中 JNI(Native方法)引用的对象

 没有被标记的对象,在下一轮GC中将会被回收。

3.现在通过可达性算法标记出要回收的对象,如何去回收这些对象

        垃圾回收算法:
              (1)标记-清除算法:

                 主要问题:

  •  效率问题 : 标记和清除这两个过程的效率都不高
  •  空间问题 : 标记清除后会产生大量不连续的内存碎片,空间碎片太多可能会导致以后在程序运行中 需要分配较大对象时,无法找到足够连续内存而不得不提前触发另一次垃圾收集。

        (2)复制算法:把内存区域1中存活的对象,复制到内存区域2中;把内存2中把对象按内存地址的顺序排列好,相当于整理内存空间;把内存区域1的空间整体清空;每次回收重复上述操作

复制算法有明显的空间利用率不足的问题,在使用时只有一般内存能够真正发挥作用

        (3)标记整理算法:回收完一块内存之后把存活的对象向一端整理。
                在移动对象的过程中,势必会将低效率

 4.在GC中到底使用哪个垃圾回收算法?

堆中:新生代,老年代

新生代:复制算法(朝生夕死)频繁GC

老年代:标记-整理算法(频繁GC后存活的对象,移动至老年代)

(1)新生代:Eden区(8)                        from(s1)(1)                        to(s2)(1)

a.所有的对象创建都在eden区开辟空间

b.当发生一轮GC之后如果对象没有被回收将会复制到From区

c.第二轮GC时会把eden和from区存活对象都复制到TO区 

d.FROM和TO互换位置

e.每次经历一次GC之后,年龄加一,当达到系统设定的年龄后(JVM默认15次后),移动到老年代

面试题:描述垃圾回收的过程?

              如果创建一个大对象,eden区放不下,那么这个对象直接放入老年区,参与标记整理算法。

新生代GC:Minor GC

老年代GC:Full GC 


垃圾回收器

当GC线程执行的时候用户的线程全部都要停止(STW)

 1.单线程收集器(内存小,配置低)

2.并行收集器,使用多线程进程进行瞄和回收

3.随着并行收集器的STW时间越来越长,又开始尝试使用新的收集器缩短STW时间CMS 、G1(全域收集器,基本不会STW)

面试题:垃圾回收器

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值