JVM系列(一)

本文探讨了为何要学习JVM,特别是其在Java和大数据中的重要性。接着,详细介绍了Linux环境下JVM的Server和Client模式的区别,并解析了几个关键参数,如PrintGCDetails、MetaspaceSize和MaxTenuringThreshold。同时,文章讲解了如何在IDEA中使用JVM命令,如jps和jinfo,并总结了不同类型的JVM参数。最后,讨论了JVM内存模型,特别是堆和非堆区域的分配以及垃圾收集器的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、Why study jvm

二、Linux上使用jvm

三、Hive中的UDF函数

四、本次课程涉及面试题

一、Why study jvm

  • 无论是Java还是大数据,都会面试JVM相关的信息,无论是性能调优还是参数监控,不管是hadoop系列还是spark系列,它都是跑在JVM之上的,就像hadoop和spark运行,一用就OOM,不同的异常信息采用不同的解决方案,JVM在生产上面是非常非常重要的,最重要的还是GC这块(垃圾收集器),从重要性上来讲,机器上都装jdk的;

  • JVM官网:https://docs.oracle.com/javase/specs/jvms/se8.html/index.html

二、Linux上使用jvm

2.1、Server和Client模式的区别

1、一般32位的Windows操作系统采用的就是Client模式的;64位的操作系统都是Server模式

2、如下在CentOS7上的是Client模式:

[root@sz5i5j-01 ~]# java -version
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)

mixed mode:混合型
Java:解释型int、编译型comp

2.2、JVM的三个参数解析

  1. jinfo -flag PrintGCDetails
  2. jinfo -flag MetaspaceSize
  3. jinfo -flag MaxTenuringThreshold
  • 学习JVM的终极目标是性能调优,与JVM相关的都是参数控制的,所以首先需要了解的是JVM参数类型:

1)、标准 --> 从jdk1到jdk12都没发生过太大变化,都是比较稳定的,比如:help、classpath
2)、X --> 在各个jdk的版本中可能会发生变化,但是变化较少
3)、XX --> 用的相对较多:
分为两类:a.boolean:定义使用:-XX:[+/-] name
-XX:+UseG1GC -XX:-UseGIGC
jps --> pid
jinfo -flag name pid
b.非boolean:-xx:name=value

面试题jdk7 --> jdk8发生的变化?
jdk7:永久代
jdk8: Metaspace

1、解释型:
[root@sz5i5j-01 ~]# java -Xint -version
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, interpreted mode)

2、编译型:
[root@sz5i5j-01 ~]# java  -Xcomp -version
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, compiled mode)
在IDEA中尝试运行:

1、写一个输出程序,sleep让这个程序睡一会:
package com.ruozedata.hadoop.jvm;

public class JvmDemo {
    public static void main(String[] args) {

        System.out.println("jvm");

        try {
            Thread.sleep(100000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}

在windows本地运行cmd,输入jps -l,查看详细正在运行的程序:

1、查看运行的进程:
C:\Users\Administrator>jps -l
10564 com.ruozedata.hadoop.jvm.JvmDemo
10264 org.jetbrains.jps.cmdline.Launcher
12712
16712 org.jetbrains.jps.cmdline.Launcher
18488
19596 sun.tools.jps.Jps

2、-表示没有开启:
C:\Users\Administrator>jinfo -flag PrintGCDetails 10564
-XX:-PrintGCDetails

3、需要在下图中Edit Configurations进行编辑才okay
C:\Users\Administrator>jps -l
7760 com.ruozedata.hadoop.jvm.JvmDemo
3828 sun.tools.jps.Jps
10264 org.jetbrains.jps.cmdline.Launcher
12712
1656 org.jetbrains.jps.cmdline.Launcher
18488

4、再次验证:+表示开启
C:\Users\Administrator>jinfo -flag PrintGCDetails 7760
-XX:+PrintGCDetails

在这里插入图片描述

  • jdk8并没有采用G1GC作为我们的垃圾回收器
布尔类型小结:

1、通过jps -l获取pid
2、jinfo -flag name pid

非布尔类型:
1、MetaSpaceSize的大小:
C:\Users\Administrator>jinfo -flag MetaspaceSize 8852
-XX:MetaspaceSize=21807104

2、修改Metaspace空间的大小:
还是去到Edit Configuration中去修改,以空格为间隔进行参数修改:
-XX:+PrintGCDetails -XX:MetaspaceSize=128m

3、修改后重新查看大小:
C:\Users\Administrator>jinfo -flag MetaspaceSize 21260
-XX:MetaspaceSize=134217728

1、年龄阈值,默认15(对象被复制的次数)

C:\Users\Administrator>jinfo -flag MaxTenuringThreshold 21260
-XX:MaxTenuringThreshold=15

2.3、Jinfo命令的详细使用

Jinfo的用法:

C:\Users\Administrator>jinfo
Usage:
    jinfo [option] <pid>
        (to connect to running process)
    jinfo [option] <executable <core>
        (to connect to a core file)
    jinfo [option] [server_id@]<remote server IP or hostname>
        (to connect to remote debug server)

where <option> is one of:
    -flag <name>         to print the value of the named VM flag
    -flag [+|-]<name>    to enable or disable the named VM flag
    -flag <name>=<value> to set the named VM flag to the given value
    -flags               to print VM flags		
    -sysprops            to print Java system properties
    <no option>          to print both of the above
    -h | -help           to print this help message
  • 1、初始堆栈内存大小:

      C:\Users\Administrator>jinfo -flag InitialHeapSize 16404
      -XX:InitialHeapSize=268435456
    
  • 2、最大堆栈内存:

      C:\Users\Administrator>jinfo -flag MaxHeapSize 16404
      -XX:MaxHeapSize=4267704320
    
  • 3、进程运行的详细信息:
    在Command line中显示的参数就是我们在IDEA项目中配置的Edit Configuration中配置的;

      C:\Users\Administrator>jinfo -flags 16404
      Attaching to process ID 16404, please wait...
      Debugger attached successfully.
      Server compiler detected.
      JVM version is 25.161-b12
      Non-default VM flags: -XX:CICompilerCount=3 -XX:InitialHeapSize=268435456 -XX:MaxHeapSize=4267704320 -XX:MaxNewSize=1422393344 -XX:MetaspaceSize=134217728 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=89128960 -XX:OldSize=179306496 -XX:+PrintGCDetails -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC
      Command line:  -XX:+PrintGCDetails -XX:MetaspaceSize=128m -javaagent:D:\intellij idea\IntelliJ IDEA 2018.1\lib\idea_rt.jar=53393:D:\intellij idea\IntelliJ IDEA 2018.1\bin -Dfile.encoding=UTF-8
    
小结:

jinfo -flag name pid
jinfo -flags pid

2.4、PrintFlags参数系列

-XX: +PrintFlagsInitial (最初始化的参数值)
-XX: -PrintFlagsFinal (可能被改过的参数值)

在Linux上把相关参数写到一个文件中去,然后grep过滤出文件中的参数:

1、把参数写到a.log中去
[root@hadoop002 ~]# java -XX:+PrintFlagsInitial > a.log
[root@hadoop002 ~]# ll
total 72
-rw-r--r-- 1 root root 72430 May 15 12:45 a.log

2、找出参数
[root@hadoop002 ~]# cat a.log|grep InitialHeapSize
    uintx InitialHeapSize                           = 0                                   {product}

3、符号表示的含义:
=	默认值
:= 修改过的

2.5、-Xmx和-Xms参数

问题:如上两个参数-Xmx和-Xms属于哪一类参数?

  • 答:属于XX参数,
    -Xms:–> min --> -XX:InitialHeapSize ( jvm堆的最小值)
    -Xmx:max --> -XX:MaxHeapSize(JVM堆的最大值)
    -Xss:全称:-XX:ThreadStackSize
这两个参数在一般情况下设置的是一样的,查看最大的Heap和最小的Heap大小

最大堆栈内存是4070m,最大堆栈内存是总内存的1/4;
C:\Users\Administrator>jinfo -flag MaxHeapSize 15104
-XX:MaxHeapSize=4267704320

初始化堆栈是256m,机器内存是16G,初始化堆栈内存一般是总内存的1/64;
C:\Users\Administrator>jinfo -flag InitialHeapSize 15104
-XX:InitialHeapSize=268435456

修改MaxHeapSize和InitialHeapSize的大小?
在IDEA的项目中直接修改参数:

  • 添加-Xmx10m -Xms10m
    在这里插入图片描述

  • 去到cmd黑窗口中进行验证:修改完后最大和最小的两个堆内存大小是一样的

1、最大堆栈就是10m
C:\Users\Administrator>jinfo -flag MaxHeapSize 18224
-XX:MaxHeapSize=10485760

2、初始堆栈也是10m
C:\Users\Administrator>jinfo -flag InitialHeapSize 18224
-XX:InitialHeapSize=10485760

3、查看这个进程的详细信息:
C:\Users\Administrator>jinfo -flags 18224
Attaching to process ID 18224, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.161-b12
Non-default VM flags: -XX:CICompilerCount=3 -XX:InitialHeapSize=10485760 -XX:MaxHeapSize=10485760 -XX:MaxNewSize=3145728 -XX:MetaspaceSize=134217728 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=3145728 -XX:OldSize=7340032 -XX:+PrintGCDetails -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC
Command line:  -XX:+PrintGCDetails -XX:MetaspaceSize=128m -Xmx10m -Xms10m -javaagent:D:\intellij idea\IntelliJ IDEA 2018.1\lib\idea_rt.jar=57657:D:\intellij idea\IntelliJ IDEA 2018.1\bin -Dfile.encoding=UTF-8

3、ThreadStackSize运行后值是0,为什么?
C:\Users\Administrator>jinfo -flag ThreadStackSize 18224
-XX:ThreadStackSize=0

2.6、JVM运行时的数据区

  • https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.5

Java运行时的数据区:是一个规范,内存结构是一个实现

The pc Register
Java Virtual Machine Stacks
Native Method Stack

运行池中包含方法区,有堆Heap,有虚拟机栈(VM Stack),本地方法栈,PC计数器;
做GC时的重点,方法区域和堆;Heap是共享的,is shared among all Java Virtual Machine Threads.
装的是对象实例和数组,会被自动的存储管理系统(GC来进行管理)

Class User{
id name
}
User user = new User()
等号左边的叫引用,右边的叫对象,对象是存储在Heap中的;JVM虚拟机是有一个方法区的,它存储的class信息的,包括常量池和实例对象;方法区在1.8中就是MetaSpace,在堆中能存东西,在MetaSpace中也能存信息。

引用(栈),对象(Heap)中,User.class(metaspace中);

2.7、JVM的内存模型

在jdk1.8中,主要分为两个区域,堆(heap)和非堆(MetaSpace),在堆中,s0和s1的大小是一样的,同一时间点只有一个是能用的,大多数场景中new出来的东西首先分配到eden区,如果eden区满了,进行垃圾回收,对象是活的,就到s1区去,每一次倒腾的过程都有1个年龄+1,年龄到了15的时候就进入了老龄代

  • CCS是什么呢,CompressedClassPointers压缩类指针,如果开启了CCS意识就是使用了短指针(32位),如果没有开启短指针,这个部分就是不存在的
    在这里插入图片描述

GC垃圾回收器的关键所在:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值