微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

jvm初步理解

1、什么是运行时数据区?

1、什么是运行时数据区

​ javac 指令:编译java文件生成class文件

​ java指令:运行class文件即将数据放到jvm中

​ class文件运行,后将不同的数据放到jvm中不同的位置这就是运行时数据区的由来

2、运行时数据区为什么要这么划分

1、class文件中到底有多少种数据类型,即JVM的整体分析

有对象,常量、静态变量、普通成员变量、方法、局部变量、父类,XXX

怎么划分?为什么要这样划分?

1、The pc Register

	<u>4、计数器(存储当前线程执行方法的记录,下次接着下去,不用从头开始。)</u>

2、java Virtual Machine Stacks

3、java虚拟机栈:

一个线程-- > 表示一个java虚拟机栈。

方法的执行,可以通过压栈的方式 --> 方法对应栈帧方法中:返回地址、局部变量、操作数

3、Heap

1、堆:存储对象【包括普通成员变量】/数组 如:new Person() class class==

4、Method Area

2、方法区:类的信息【创建时间,元数据信息】、常量、静态变量、即时编译器编译之后的代码

堆和方法区都是线程共享,由于其他线程共享也就是说是线程不安全。

5、Run-time constant pool

6、属于方法区的一部分

6、Native Method Stacks

5、如果不是Native(本地)方法,那就是用来存储运行到那个方法的位置。

3、方法的执行和java虚拟机栈详解

jvm整体图:

1、方法区的别名:

方法区,包含了运行时常量池

Method Area 方法

​ JDK1.7 之前 ---> Perm Space 永久代

​ JDK1.8 之后 --> MetaSpace 元空间

2、java虚拟机,运行压栈的过程

/*java文件方法*/
public static int calc(int op1,int op2) {
    op1=3;
    int result =op1+op2;
    return result;
}


/*生成的class文件*/
public static int calc(int,int);
	Code:
	   0: iconst_3
       1: istore_0  # 3这个数值从操作数栈中弹出来
       2:iload_0
       3: iload_1
       4: iadd
       5: istore_2
       6: iload_2
       7: ireturn

4、垃圾回收器和垃圾回收算法

垃圾回收

垃圾判断:

垃圾回收算法:复制 标记-整理

我有一个块内存区域

1、原因

java进程启动时候,有一个initiaHeapSize,我是可以跟计算机要一个间的,进行这个进程的数据保存

initiaHeapSize = 100M --> 有一块100M的物理内存,可以向计算机要内存的。

我有一块内存区域,存着存着,发现不够用了,怎么办? 不够用了将会报错--->OutOfMemoryError

万一这个内存区域中,有些数据已经彻底没用了,我们把它称作垃圾,对应的垃圾回收算法对其进行回收

2、内存模型

  1. 向计算机获取一个内存,即内存模型
  2. 内存分为:方法区,堆(保存对象)
  3. 堆又分为:老年代、新生代(保存对象满触发GC垃圾回收,删除垃圾对象,老年区和新生代的界限是15次GC,若还存在就放到老年区。)

  1. 相对于新生代而言,老年代占用空间更大,触发GC的时间更长,因此尽量减少从新生代中放对象到老年区。

    因此需要一个缓冲,将新生代分为两个部分:Eden(生成新对象在这里),Suvivor(在Eden的GC处理后的对象放到Suvivor中,Suvivor在GC后才放到老年区

  1. Suvivor中由于有些零碎的空间,但加进来的对象需要相连的空间才能存放,所以Suvivor有分为:两个Suvivor:From 、to,每时每刻永远有一块是空的,永远有一块是满的。

  2. Suvivor中from和to可以相互转换(每时每刻都已一个是空的),如下图:

3、问题:如果Eden 占80M,S0 From 占10M, S1 To 占10M。那是不是意味着没时每刻都已10%的空间是浪费的。

​ 没错,我们就是要用这样的浪费来,获取50%的连续。

4、问题:什么样的对象才算是垃圾

  1. 用法

    如果是A引用B,B引用A,相互引用那么这两者永远都不会成为垃圾,永远都会占用内存空间,这样不合适。

  1. 可达性分析:有GC root出发

回收 -->

4、回收算法:用一定的算法的方式去回收这些垃圾 3种

1、标记-清除

找出内存需要回收的对象,并且把它们标记出来

此时堆中所有的对象都会被扫描一遍,从而才能确定需要回收的对象,比较耗时。

清除垃圾对象

弊端:比较耗时(需要扫描真个内存空间,然后清除垃圾),空间碎片(不连续)

2、复制标记

耗时(是将存活的对象移动到,另一个间的时间)

3、标记整理

将存活的对象,移动

堆:Old Young(Eden、S0和S1)

到底哪个算法用在哪个区域呢?

不同的代用不同的垃圾回收算法

Young区,复制--->前提条件:每次垃圾回收 存活的对象都比较少 ---> 复制算法

​ 绝大多数的对象都被回收掉 --> Eden和Eden(S0 From和S1 To)

Old区呢?

​ 一般是存活时间比较长,意味着很难被回收 ---> 标记-整理、标记清除

4、会不会要我去设计垃圾回收算法呢?

1、落地垃圾回收算法

垃圾收集器(常用的G1处理器)

2、G1垃圾收集器的过程

  1. 初识标记

    使用一个垃圾回收线程,进行初识标记,注意此时其他用户线程暂定了

    标记的是什么样的对象是垃圾标记一下GC Roots能够直接关联到的对象,Stop the world

  2. 并发标记

    从GC Roots触发可达性 存活的对象

  3. 最终标记

    最终标记 再次标记 many GC Threads

  4. 筛选回收

    回收垃圾对象 Stop the world

5、评价一个垃圾收集器的好坏的标准:

  1. 吞吐量 吞吐量越高 越好
  2. 停顿时间 停顿时间 越低越好

6、减少GC的频率 -----G1

1、适当地增加对内存空间 (这样存放对象的空间变大,GC执行的时间变长)

2、合理的设计G1垃圾收集器的停顿时间 (一般认都回收一定的停顿时间,可以增加

3、垃圾回收的临界线

-XX:InitiatingHeapOccupancPercent = 50 (如一般到占内存的40%,就触发GC垃圾回收,可以设置到50%)

4、增加垃圾回收线程数量增加线程回收,空出内存)

-XX:ConGCThreads =10

Young GC:可以称为 Minor GC

old GC:可以称为 Major

也就是:

Young + Old ===>(等同于) Minor GC + Major GC ===> Full GC

老年区触发的GC 是Full GC

这就是JVM

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐