从零开始的Java再学习-DAY7

JVM

1.JVM概述

1.JVM是Java虚拟机,通过软件来模拟Java字节码的指令集,是Java程序的运行环境,位于操作系统上层;

2.三种JVM

1.dos命令:java -version;

2.sun公司: HotSpot™ 64-Bit Server VM(常用);

3.BEA公司:JRockit;

4.Oracle公司:IBM;

3.JVM的体系结构

1.类加载器子系统,运行时数据区,执行引擎;

在这里插入图片描述

4.类加载器

1.Java虚拟机自带的类加载器,启动类(根)加载器(rt.jar),扩展类加载器(ext),应用程序类加载器;

5.双亲委派机制和沙箱安全机制

1.双亲委派机制是当运行一个包的类时会通过应用程序,扩展,根加载器一层层递进寻找,若根加载器存在则直接运行根加载器的,若没有则返回下一层寻找,直至运行,主要为确保安全;

2.沙箱安全机制是将java代码限定在jvm特定的运行范围中,限制系统资源访问,对代码进行有效隔离防止本地系统造成破坏;

3.组成沙箱的基本组件有:字节码校检器(确保遵守java语言规范),
类加载器(因为双亲委派可以让类加载器起到防止恶意代码干涉善意代码,守护被信任的类库边界,而类加载器本身可将代码归入保护域),
存取控制器(用户可设定核心API对操作系统的存取权限),
安全管理器(核心API和操作系统间的主要接口,实现权限控制,比存取控制器优先级高);

6.native

1.native说明的是Java作用域达不到,需要调用底层c语言的库。进入到本地方法栈登记native方法,然后去调用本地方法接口(JNI),JNI再去本地方法库调用执行;

2.JNI主要扩展了java的使用,可以融合其他编程语言为Java所用;

7.PC寄存器

1.又叫程序计数器,每个线程都有一个,是线程私有的,本质是指针;

2.它所占内存空间非常小,几乎忽略不计;

3.它指向方法区的方法字节码(用来存储指向一条像指令的地址,即将要执行的指令代码),在执行引擎中读取下一条指令;

8.方法区

1.它被所有线程共享;

2.所有字段,方法字节码,特殊方法(构造函数,接口代码)都保存在该区域;

3.静态变量,常量,类信息(Class模板,接口定义,构造方法)运行时的常量池存在方法区中,但实例变量存在堆内存中;

9.栈

1.先进后出,后进先出,可以举例为方法的花括号“{}”,先写的“{”会在最后才“}”;

2.栈为空即程序结束,这也是为什么main方法先执行却最后结束;

3.递归的自身调用或死锁式调用会导致栈内存溢出;

4.栈存放8大基本类型+对象引用+实例方法;

5.栈运行的原理为栈帧;

10.堆

1.一个JVM只有一个堆内存,大小可以调节;

2.存放所有类型的真实对象;

3.堆内存溢出报错OOM(OutOfMemoryError);

4.堆又分为新生区,养老区。永久区不属于堆但占用堆内存;

11.新生区,老年区,永久区

1.新生区又分为伊甸园区和养老区,伊甸园区是所有对象出生(new)的地方,幸存区用于存放在伊甸园区经过轻量级GC存活下来的对象,当新生区内存满了就进行重量级GC;

2.老年区是存放经历了多次(默认15次)GC的新生区对象;

3.永久区是常驻的,用来存放JDK本身携带的Class对象,interface元数据,一些java运行环境或类信息;

4.永久区在jdk1.6之前是有永久代,常量池在方法区中,1.7也有永久代,但常量池在堆中,1.8之后去除永久代,常量池放在元空间里(永久区+方法区),与堆区分,内存占用本地内存;

5.永久区不存在垃圾回收,JVM关闭内存就会释放;

12.堆内存调优

1.当出现OOM故障时可通过内存快照分析工具(MAT,jprofiler)快速定位出错代码;

2.内存快照分析工具分析Dump内存文件,快速定位内存泄漏,获得堆中数据和大的对象等;

3.调优三大参数:-Xms(设置初始化内存分配大小,一般为内存的1/64),
-Xmx(设置最大分配内存,一般为内存的1/4),
-XX:+方法(如PrintGCDetails//打印gc垃圾回收信息,HeapDumpOnOutOfMemoryError//生成dump文件,用于jprofiler查看问题,MaxTenuringThreshold=xxx//进入老年区经历的GC次数);

package JVM_Deemo;

import java.util.ArrayList;

public class TestJVM {

    byte[] array=new byte[1*1024*1024];

    public static void main(String[] args) {
        //获取jvm堆内存的最大分配内存和初始化内存
        long max=Runtime.getRuntime().maxMemory();
        long total=Runtime.getRuntime().totalMemory();

        System.out.println("max:"+max+"字节\t"+(max/(double)1024/1024)+"mb");
        System.out.println("total:"+total+"字节\t"+(total/(double)1024/1024)+"mb");
        System.out.println("=============");

        //jvm堆内存通过运行键旁边的框可进入VM堆修改内存
        //-Xms64m -Xmx1024m -XX:+PrintGCDetails,对应初始内存,最大内存,方法

        //模拟OOM并dump下文件,通过HeapDumpOnOutOfMemoryError在VM编译生成
        ArrayList<TestJVM> list = new ArrayList<>();
        int count=0;

        try {
            while (true) {
                list.add(new TestJVM());
                count++;
            }
        }catch (Exception e){
            System.out.println("count:"+count);
            e.printStackTrace();
        }
    }
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

13.GC机制

1.当堆内存的各区内存满了后会进行一次GC,即垃圾回收;

2.GC垃圾回收主要回收新生区;

3.GC有轻量级(普通)和重量级(全局);

4.新生区的幸存区分为2个,一个from区一个to区,动态交替存在;

14.GC算法:

1.引用计数法:通过分配一个计数器给对象计数调用的次数,次数少则回收对象,缺点为分配需要消耗,计数器本身也为消耗,在多次循环的结构会很消耗,故很少采用;

2.复制算法:每次GC伊甸园区后存活下来的对象会进入到幸存区,幸存区的to区永远为空,但两个分区都不为空就进行复制方法把一个区的对象复制到另一个区,空的区永远为to区,好处是没有内存碎片,缺点就是浪费了一个to区不能用,该算法主要用在存活率低的区域,即新生区;

3.标记清除压缩算法:GC时扫描3次,第一次标记不被清除的,第二次把为被标记的清除,第三次扫描压缩内存碎片,好处就是不想复制算法浪费一个空间,缺点就是扫描次数多,耗时久,多用于老年区;

15.JMM(Java Memory Model)

1.java内存模型,围绕着在并发过程中如何处理可见性、原子性、有序性这三个特性而建立的模型。

2.作用:缓存一致性协议,用于定义数据读写的规则。JMM定义了线程工作内存和主内存之间的抽象关系,线程之间的共享变量存储在主内存中,每个线程都有自己的私有本地内存。

3.可见性:JMM提供了volatile变量定义、final、synchronized块来保证可见性;
原子性:JMM提供保证了访问基本数据类型的原子性(其实在写一个工作内存变量到主内存是分主要两步:store、write),通过synchronized块保证;
有序性:模型提供了volatile和synchronized来保证线程之间操作的有序性。

4.在执行程序时为了提高性能,编译器和处理器常常会对指令做重排序(编译器、处理器),就是因为这些重排序,所以可能会导致多线程程序出现内存可见性问题(数据安全问题)和有序性问题。JMM是通过禁止特定类型的编译器重排序和处理器重排序(插入特定类型的内存屏障)来为程序员提供一致的内存可见性保证。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值