JVM基础详解

1.JVM的位置

(图均出自狂神)

在这里插入图片描述

2.JVM的体系结构

在这里插入图片描述

3.类加载器

作用:加载class文件 ~
在这里插入图片描述

3.1虚拟机自带的加载器

3.2启动类(根)加载器

3.3扩展类加载器

3.4用户应用程序加载器

4 双亲委派机制

  1. 类加载器收到类加载的请求
  2. 将这个请求向上委托给父类父类加载器去完成,一直向上委托,知道启动(根)类加载器
  3. 启动加载器检查是否能加载当前这个类(jre/lib/rt.jar),能加载就使用当前加载器,否则抛出异常,通知子加载器进行加载
  4. 重复步骤3
    classNotFound~
    java 调用不到跟加载器,调用不到C C++
    在这里插入图片描述
public class TestClassLoader {

    public static void main(String[] args) {
        Car car1 = new Car();
        Car car2 = new Car();
        Car car3 = new Car();

        System.out.println(car1.hashCode());
        System.out.println(car2.hashCode());
        System.out.println(car3.hashCode());

        System.out.println(car1.getClass().hashCode());
        System.out.println(car2.getClass().hashCode());
        System.out.println(car3.getClass().hashCode());

        Class<? extends Car> aClass = car1.getClass();

        System.out.println(aClass.getClassLoader());//AppClassLoader
        System.out.println(aClass.getClassLoader().getParent());//ExtClassLoader
        System.out.println(aClass.getClassLoader().getParent().getParent());// null java程序获取不到
    }

}

class Car {

}

运行结果:

"C:\Program Files\Java\jdk1.8.0_181\bin\java.exe" "-javaagent:D:\software\IntelliJ IDEA 2019.3.1\lib\idea_rt.jar=57820:D:\software\IntelliJ IDEA 2019.3.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_181\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\rt.jar;D:\InreliJWorkSpace\InterviewCoding\out\production\InterviewCoding" com.codingInterview.jvm.classloader.TestClassLoader
1163157884
1956725890
356573597
1735600054
1735600054
1735600054
sun.misc.Launcher$AppClassLoader@18b4aac2
sun.misc.Launcher$ExtClassLoader@14ae5a5
null

Process finished with exit code 0

5 沙箱安全机制

沙箱安全机制是限制程序运行的一个环境,主要是限制系统资源的访问,jvm本地代码是安全的,是可以直接操作操作系统和本地资源的,对于远程代码则需要授信,才可以访问本地资源和操作系统。
组成沙箱的基本条件:
字节码校验器(bytecode verify),校验java类文件是否符合java的语言规范,,可以帮助java程序实现内存保护,(核心类不需要,Java自己提供的安全的类)
类装载器(class loader):在三个方面对沙箱起作用

  • 防止恶意代码去篡改善意的代码; //双亲委派机制
  • 守护了被信任的类库的边界 //双亲委派机制
  • 将代码归入了保护域,确定了那些代码可以执行操作

6 Native 关键字

native : 凡是带了native 关键字的 , 说明java已经执行不到了,是回去调用底层的C语言的库
会进入本地方法栈,调用本地方法接口JNI
JNI作用:提供本地方法的接口,使Java可以支持多方的代码(C,C++)
Java诞生之初,是为了可以简化C++,去掉了指针,析构等堆内存的直接调用,加入了GC等等,在当时的情况下,java如果想要立足,必须在C,C++横行的市场取得一席之地。
在内存区域中专门开辟了一块标记区域,Native Method Stack
本地方法栈,以用来等级Native方法
在最终执行时,加载本地方法库中的方法是通过JNI进行调用
在这里插入图片描述

7 栈

先进后出,不多废话,喝多了吐
不存在垃圾回收,一旦线程结束,栈也结束,一旦有垃圾,基本就是栈溢出了
栈:8大基本类型+对象的引用+实例的方法

栈的运行原理:栈帧-每执行的一个方法都会产生一个栈帧
(程序正在执行的方法,一定在栈的顶部)
如果栈被推满,就会抛出 StackOverFlowError
在这里插入图片描述
new 一个对象在内存中的过程:
在这里插入图片描述

7 堆

三种JVM

  • 孙公司 - Hotspot
  • BEA oracle JRockit
  • IBM J9VM (本人公司在用)

Heap , 一个JVM只有一个堆内存,堆内存的大小是可以调节的
类加载器读取了类文件后, 一般会把类的具体实例放到堆中
类,方法,常量,变量,保存所有引用类型的真实对象

  • 新生区

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

  • 永久区(1.8之后无永久区,变为元空间)
    这个区域是常驻内存(用来存放JDK自身携带的Class对象。Interfase元数据,存储的是JAva运行时的一些环境类的信息,不存在垃圾回收,关闭JVM虚拟机就会释放这个区域中的内存~)
    一个启动类加载了大量的第三方jar包。Tomcat部署了太多的应用,大量的动态生成的反射类不断被加载。直到内存慢,就会出现OOM (实例:web项目启动时加载Rule xml文件,其中有配置语法错误的xml ,导致该xml加载类不断去循环读取xml PS:至今没明白为什么会不断循环加载,可能有try catch捕获,导致OOM)

    • jdk1.6之前 :永久代,常量池在方法区
    • jdk 1.7 :永久代,慢慢退化,常量池在堆中
    • jdk 1.8之后:无永久代,常量池在元空间
      (捕捉大佬弹幕一条:因为常量池不好控制,方法区又小,所以之前经常会出现永久带溢出)
      GC 垃圾回收,主要存在新生代和老年代
      假设堆内存满了,OOM,堆内存不够
      项目实例:
      本人项目中曾经历过一次OOM,在struts升级tile3后因为配置文件错误导致两个action循环调用,产生新的reqeust ,不断产生新的action对象撑爆内存。
      在这里插入图片描述
      -Xms1024m -Xmx1024m -XX:+PrintGCDetails
      -Xms1024m -Xmx1024m -XX:+HeapDumpOnOutOfMemoryError
public class TestHeap {
    public static void main(String[] args) {
        String a= "只要学不死,就往死里学";
        while (true){
            a += a+new Random().nextInt(999999999)+new Random().nextInt(999999999);
        }
    }
}

运行结果:

[GC (Allocation Failure) [PSYoungGen: 61329K->4452K(76288K)] 61329K->19035K(251392K), 0.0092068 secs] [Times: user=0.06 sys=0.02, real=0.01 secs] 
[GC (Allocation Failure) [PSYoungGen: 64038K->8015K(141824K)] 78622K->51751K(316928K), 0.0152294 secs] [Times: user=0.03 sys=0.05, real=0.02 secs] 
[GC (Allocation Failure) [PSYoungGen: 129829K->760K(141824K)] 173564K->117375K(316928K), 0.0309017 secs] [Times: user=0.09 sys=0.03, real=0.03 secs] 
[Full GC (Ergonomics) [PSYoungGen: 760K->0K(141824K)] [ParOldGen: 116615K->73529K(225792K)] 117375K->73529K(367616K), [Metaspace: 3455K->3455K(1056768K)], 0.0092777 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
[Full GC (Ergonomics) [PSYoungGen: 119165K->0K(141824K)] [ParOldGen: 190137K->146409K(317952K)] 309303K->146409K(459776K), [Metaspace: 3455K->3455K(1056768K)], 0.0197589 secs] [Times: user=0.05 sys=0.00, real=0.02 secs] 
[GC (Allocation Failure) [PSYoungGen: 124430K->448K(220160K)] 2486390K->2420719K(3011072K), 0.0259856 secs] [Times: user=0.13 sys=0.02, real=0.03 secs] 
[GC (Allocation Failure) [PSYoungGen: 448K->416K(262656K)] 2420719K->2420687K(3053568K), 0.0079878 secs] [Times: user=0.09 sys=0.00, real=0.01 secs] 
[Full GC (Allocation Failure) [PSYoungGen: 416K->0K(262656K)] [ParOldGen: 2420271K->700630K(921600K)] 2420687K->700630K(1184256K), [Metaspace: 3951K->3951K(1056768K)], 0.1725515 secs] [Times: user=0.28 sys=0.14, real=0.17 secs] 
[GC (Allocation Failure) [PSYoungGen: 4986K->32K(399872K)] 2571343K->2566389K(3190784K), 0.0063353 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
[GC (Allocation Failure) [PSYoungGen: 32K->32K(399360K)] 2566389K->2566389K(3190272K), 0.0063244 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
[Full GC (Allocation Failure) [PSYoungGen: 32K->0K(399360K)] [ParOldGen: 2566357K->933845K(1180672K)] 2566389K->933845K(1580032K), [Metaspace: 3951K->3951K(1056768K)], 0.1720655 secs] [Times: user=0.42 sys=0.08, real=0.17 secs] 
[GC (Allocation Failure) [PSYoungGen: 0K->0K(692224K)] 1866709K->1866709K(3483136K), 0.0033562 secs] [Times: user=0.09 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [PSYoungGen: 0K->0K(709632K)] 1866709K->1866709K(3500544K), 0.0040389 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (Allocation Failure) [PSYoungGen: 0K->0K(709632K)] [ParOldGen: 1866709K->1400277K(1677824K)] 1866709K->1400277K(2387456K), [Metaspace: 3951K->3951K(1056768K)], 0.1038534 secs] [Times: user=0.44 sys=0.02, real=0.10 secs] 
[GC (Allocation Failure) [PSYoungGen: 0K->0K(1022464K)] 1400277K->1400277K(3813376K), 0.0027090 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (Allocation Failure) [PSYoungGen: 0K->0K(1022464K)] [ParOldGen: 1400277K->1400223K(1706496K)] 1400277K->1400223K(2728960K), [Metaspace: 3951K->3951K(1056768K)], 0.1778106 secs] [Times: user=0.78 sys=0.00, real=0.18 secs] 
Heap
 PSYoungGen      total 1022464K, used 30449K [0x000000076ad80000, 0x00000007aa880000, 0x00000007c0000000)
  eden space 1021952K, 2% used [0x000000076ad80000,0x000000076cb3c570,0x00000007a9380000)
  from space 512K, 0% used [0x00000007aa800000,0x00000007aa800000,0x00000007aa880000)
  to   space 7680K, 0% used [0x00000007a9980000,0x00000007a9980000,0x00000007aa100000)
 ParOldGen       total 2790912K, used 1400223K [0x00000006c0800000, 0x000000076ad80000, 0x000000076ad80000)
  object space 2790912K, 50% used [0x00000006c0800000,0x0000000715f67da0,0x000000076ad80000)
 Metaspace       used 3983K, capacity 4568K, committed 4864K, reserved 1056768K
  class space    used 437K, capacity 460K, committed 512K, reserved 1048576K
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at java.util.Arrays.copyOf(Arrays.java:3332)
	at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:124)
	at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:674)
	at java.lang.StringBuilder.append(StringBuilder.java:208)
	at com.codingInterview.jvm.heap.TestHeap.main(TestHeap.java:9)

8 内存快照 OOM排错

Eclipse : MAT
软件 : Jprofiler

L-Larry_Lau@163.com#23874-hrwpdp1sh1wrn#0620 
L-Larry_Lau@163.com#36573-fdkscp15axjj6#25257 
L-Larry_Lau@163.com#5481-ucjn4a16rvd98#6038 
L-Larry_Lau@163.com#99016-hli5ay1ylizjj#27215 
L-Larry_Lau@163.com#40775-3wle0g1uin5c1#0674 
 
转载于:https://www.cnblogs.com/yepei/p/7081074.html

Dump文件抓取内存快照来分析
在这里插入图片描述
在这里插入图片描述

题目:

  • Jvm的内存模型和分区 详细到每个区放什么
  • 堆的分区有哪些,说说他们的特点
  • GC的算法有哪些
  • 轻GC 和 重GC分别在什么时候发生

9 GC

9.1 引用器计数法:

计数器对每一个对象的引用次数进行技术,选择引用很少0的对象进行回收(JVM 不使用)

9.2 复制算法:

总结:
1.在每次Eden区的对象经历过一次垃圾回收之后,将活着的对象移到幸存区,经历一次GC后,Eden内存清空
2.将幸存的对象复制到幸存From区(空幸存区),同时,将原From区的幸存对象一并复制,放入空幸存区,形成新的From区,将原来的有幸村对象的幸存区清空,成为新的幸存To区
在这里插入图片描述
优点:没有内存碎片
缺点:占用内存空间(幸存to区,他是空的)
面试经历:(敲黑板)
Ali:对象在Jvm中什么情况下会从新生代转移到老年代
面试的我:不知道
现在的我:在对象一个对象经历了15次(默认)轻GC后,仍然存活,则会将其从新生代移动至老年代养老
且,该过程可以使用JVM调优参数"-XX:MaxTenuringThreshuld=15"进行调优。

标记压缩清除算法
在这里插入图片描述

10 JMM - Java Memory Model

Volitale and Synchronized.
可见性,有序性,原子性
缺总结~明天补 mark
完结撒花

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值