JVM整理


去有几部分成?

方法区

程序数器

本地方法

 

 

如何判断一个象是否可以被回

引用数算法

为对象添加一个引用数器,当加一个引用时计数器加 1,引用失时计数器 1。引用 0 的象可被回

象出引用的情况下,此引用数器永 0,们进行回

性分析算法

以 GC Roots 起始点索,可象都是存活的,不可象可被回

 

 

GC的触条件是什

Minor GC,其触条件非常简单,当 Eden 空间满时或者象分配不了,就将触一次 Minor GC。

Full GC 对复杂,有以下条件:

用 System.gc()是建行 Full GC,但是虚机不一定真正去行。不建使用这种方式,而是机管理内存。

老年代空不足老年代空不足的常见场前文所的大象直接入老年代、期存活的入老年代等。

 

 

Java是根行可性分析的?

GC ROOTS。

GC ROOTS可以的象有:

中的引用

方法区的类变量的引用

方法区中的常量引用

本地方法中的象引用

 

 

JVM七种垃圾集器?

Serial 集器 (制算法,单线程,新生代)

ParNew 集器 制算法,多线程,新生代)

Parallel Scavenge 集器(多线程,制算法,新生代,高吐量)

Serial Old 集器(标记-整理算法,老年代)

Parallel Old 集器(标记-整理算法,老年代,注重吐量的景下,jdk8采用 Parallel Scavenge + Parallel Old 的合)

CMS 集器(标记-清除算法,老年代,垃圾线程几乎能到与用户线程同工作,吐量低,内存片)以吐量得最短回顿时间-XX:+UseConcMarkSweepGC

jdk1.8 认垃圾集器Parallel Scavenge(新生代)+Parallel Old(老年代) jdk1.9 认垃圾集器G1

 

 

JVM年代到年老代的晋升程的判断条件是什

部分象会在 From 和 To 区域中制来制去,如此交 15 次(由 JVM 参数 MaxTenuringThreshold 决定,个参数是 15),最如果是存活,就存入到老年代;

 

如果象的大小大于 Eden 的二分之一会直接分配在 old,如果 old 也分配不下,会一次 majorGC,如果小于 eden 的一半但是没有足的空,就行 minorgc 也就是新生代 GC;

minor gc 后,survivor 然放不下,放到老年代;

 

动态判断 ,大于等于某个年象超了 survivor 空一半 ,大于等于某个年象直接入老年代;

 

 

垃圾集算法都有

 

引用数法

概述:给对象中添加一个引用数器,当有一个地方引用数器就加1;当引用失数器1;任何数器都0的象就是不再被使用的,垃圾集器将回该对象使用的内存。

点:

点:引用集器可以快的行,交在程序行中。程序需要不被长时间打断的实时环境比有利。

点:检测出循引用。如父象有一个象的引用,子象反来引用父象。这样,他的引用数永不可能0.而且次加非常浪内存。

 

索算法

在Java中可作GC roots的象可以有以下几

中引用的

方法区中属性引用的

方法区中的常量引用的

本地方法的引用

 

标记清除算法标记-清除(Mark-Sweep)

算法名思,主要就是作,一个是标记一个就是清除。标记就是根特定的算法(如:引用数算法,可性分析算法等)出内存中象可以回继续用。标记指示回,那就直接收掉标记指示能用,那就原地不留下。

点1.标记与清除率低;2.清除之后内存会生大量片(因容易造成不连续);所以问题还理,怎么处理,看标记-整理算法。

 

制算法

S0和s1将可用内存容量分成大小相等的两块使用其中一,当这块内存使用完了,就将存活的制到内存上去,然后把使用的内存空一次清理这样使得次都是其中一内存行回,内存分配不用考内存片等复杂情况,需要移序分配内存即可,实现简单行高制算法的而易,可使用的内存降原来一半。制算法用于在新生代垃圾

存在于新生代S0和S1之点是空利用率比低。

 

标记-整理算法

标记压缩法在标记清除基之上化,把存活的压缩到内存一端,而后垃圾清理。(java中老年代使用的就是标记压缩法)

就是标记清除算法的升版,一次GC之后整理空然后在回

 

分代集算法

内存中象的存活周期不同,将内存,java的虚机中一般把内存新生代和年老代,当新一般在新生代中分配内存空,当新生代垃圾集器回几次之后然存活的象会被移到年老代内存中,当大象在新生代中到足连续内存也直接在年老代中建。于新生代和老年代来,新生代回高,但是次回短,而老年代回低,但是耗会相对较长,所以应该尽量少老年代的GC.

垃圾的停顿现垃圾的任识别和回垃圾对行内存清理,让垃圾器可以更高行,大部分情况下,会要求系统进如一个停的状。停的目的是止所有的线程,这样的系才不会有新垃圾生。同了系在某一个瞬的一致性,也有利于更好的标记垃圾对象。因此在垃圾,都会用程序的停

 

是双委派

在JVM虚机中,如果一个求,首先不会自己去尝试载这,而是把求委派器完成。器都是如此,有当父加器在自己的范围不到指定的类时(即ClassNotFoundException),子加器才会尝试自己去加。也就是器,有父(依次递归不到,才自己加就是双委派模型。

向上委实际上就是查找缓存,看上是否加该类,有直接返回,没有则继续向上。当到达顶层之后,是没有的话则开始向下查找

向下查找查找路径,有返回,没有则继续向下查找

 

JVM

1、子系:

负责文件系或者Class信息,加的信息存放在一称之方法区的内存空

 

2、方法区:

就是存放的信息、常量信息、常量池信息、包括字符串字面量和数字常量等。通常和永久区(Perm)在一起。

 

3、Java堆:

和程序开发密切相

用系统对象都保存在Java堆中

所有线程共享Java堆

分代GC来,堆也是分代的

GC的主要工作区

 

4、直接内存:

JavaNioJava程序直接内存,而提高性能,通常直接内存速度会于Java堆。繁的合可能会考使用。

 

5、Java

线程私有

由一系列帧组成(因此Java叫做帧栈

保存一个方法的局部量、操作数、常量池指

一次方法建一个,并压栈

 

6、本地方法

最大不同本地方法用于本地方法用。

 

7、垃圾集系是Java的核心,也是不可少的,Java有一自己垃圾清理的机制。

 

8、PC(Program Couneter)寄存器也是线程私有的空, Java虚机会为每线建PC寄存器,在任意刻,一个Java线是在行一个方法,个方法称当前方法,如果当前方法不是本地方法,PC寄存器行当前正在被行的指令,如果是本地方法,PC寄存器值为Underfined,寄存器存放如果当前境指、程序技器、操作算的量指等信息。

 

9、虚机核心的件就是行引负责执行虚机的字节码,一般编译成机器行。

 

YoungGC的程是什

首先,所有新建的象都会分配到年代的 Eden 空,而个 survior 空始都空。

表示的是行一段实际后的年代内存情况,新建的象会被放在 Eden 空,“from” survior space 里面的数字表示当前内存块经历垃圾次数。没经历一次垃圾,内存的数字就加一,所有数字越大,明存在的时间越久。

当 Eden 空被填,就会触垃圾

次回,需要清理 Eden 空的全部象,没有被用的象会比清除,幸存下来的象全部被移到 s0 幸存空,并标记经历的回次数 1 。若 s0 幸存空法装下所有 Eden 来的幸存象,多出来的象会被直接移到老年代空略了上 3, 1 内存

第二次行次垃圾,Eden 空间发生同的事情,没有被引用的象被除,被引用的象被移到幸存区空次移到一个幸存区空 s1 。若 s1 的空不足以装下所有的来自 Eden 的幸存象,象直接被移到老年代。上一次存幸存空的 s0 也被垃圾,幸存下来的象年加1,并被移到 s1 幸存区。同地,若 s1 法装下所有移来的幸存象,象被直接移到老年代。清空 s0 空

下一次次垃圾理流程一是幸存区调转被引用的象被移到 s0 空。幸存下来的象年加1,Eden 和 s1 空被清空。

4、5幸存区 s0, s1 中,有一个是空的。

演示象升。在某次次垃圾后,当一到某个年纪阀门(本例子是 8 ),便代升到老年代。

着次垃圾行,不停地升迁对象到老年代空

上面,几乎了年代的全部流程步骤。最,会行主垃圾,清理并压缩老年代空

 

的生命周期

(Loading)

验证(Verification)

(Preparation)

解析(Resolution)

初始化(Initialization)

使用(Using)

(Unloading)

 

Java的器有

Jdk的有三个器,BootstrapClassLoader,ExtClassLoader,AppClassLoader

BootstrapClassLoader 是ExtClassLoader的父器,认负责java_home下的lib和class文件。

ExtClassLoader是AppClassLoader的父负责java_home的lib下的ext文件下jar和class文件

AppClassLoader是自定义类器的父负责classpath下的文件。

GC Roots的根点有

线程的本地量,静态变量,本地方发栈

 

例模式

 

//dcl

 

public class Singleton {

 

 

    private volatile static Singleton uniqueInstance;

 

 

    private Singleton() {

    }

 

 

    public static Singleton getUniqueInstance() {

        if (uniqueInstance == null) {

            synchronized (Singleton.class) {

                if (uniqueInstance == null) {

                    uniqueInstance = new Singleton();

                }

            }

        }

        return uniqueInstance;

    }

}

 

值传递和引用传递

象被值传递,意味着传递象的一个副本。因此,就算是改象副本,也不会影象的

象被引用传递,意味着传递的并不是实际象,而是象的引用。因此,外部引用象所的改会反映到所有的象上。

 

与重写?

:存在于同一个中,指一个方法与已存在的方法名称上相同,但是参数型、个数、序至少有一个不同。

应该注意的是,返回不同,其都相同不算是重

重写:存在于承体系中,指子类实现了一个与父在方法声明上完全相同的一个方法。

 

序列化

转换为序列的程称为对象的序列化。 成二制流 序列化 二制流转对象 反序列化 serialVersionUID 是一个序列化版本号,Java 通过这个 UID 来判定反序列化的字流与本地的一致性,如果相同则认为一致, 可以行反序列化,如果不同就会常。

Java序列化算法 所有保存到磁象都有一个序列化编码号 当程序试图序列化一个,会先检查象是否已序列化有此未(在此虚机)被序列化,才会将此象序列化序列出。 如果此象已序列化直接号即可。

 

常用的序列化方式都有

 

1) Java 原生序列化方式参考以下代

        User user = new User();

        user.setName("老王");

        user.setAge(30);

        System.out.println(user);

        // 出流(序列化内容到磁

        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(

                    "test.out"));

        // 序列化

        oos.writeObject(user);

        oos.flush();

        oos.close();

        // 入流(反序列化)

        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(

                    "test.out"));

        // 反序列化

        User user2 = (User) ois.readObject();

        ois.close();

        System.out.println(user2);

  2) JSON 格式,可使用 fastjson 或 GSON

        User user = new User();

        user.setName("老王");

        user.setAge(30);

        System.out.println(user);

        String jsonSerialize = JSON.toJSONString(user);

        User user3 = (User) JSON.parseObject(jsonSerialize, User.class);

        System.out.println(user3);

  3)Hessian 方式序列化Hessian 序列化的点是可以跨言,比 Java 原生的序列化和反序列化率高.

        // 序列化

        ByteArrayOutputStream bo = new ByteArrayOutputStream();

        HessianOutput hessianOutput = new HessianOutput(bo);

        hessianOutput.writeObject(user);

        byte[] hessianBytes = bo.toByteArray();

        // 反序列化

        ByteArrayInputStream bi = new ByteArrayInputStream(hessianBytes);

        HessianInput hessianInput = new HessianInput(bi);

        User user4 = (User) hessianInput.readObject();

        System.out.println(user4);

 

与浅

建一个新象,象有着原始象属性的一。如果属性是基本型,的就是基本型的,如果属性是引用型,的就是内存地,所以如果其中一个象改个地,就会影一个象。

是将一个内存中完整的出来,堆内存中辟一个新的区域存放新象,且修改新象不会影象。

var a1 = {b: {c: {}};

var a2 = shallowClone(a1); // 浅方法

a2.b.c === a1.b.c // true 新旧是共享同一内存

var a3 = deepClone(a3); // 深方法

a3.b.c === a1.b.c // false 新象不共享内存