Java——JVM学习(周阳)

1. 概述

在这里插入图片描述
橙色区域:所有线程共享,存在GC(垃圾回收)
灰色区域:线程私有
在这里插入图片描述

在这里插入图片描述

2. 类加载器

在这里插入图片描述
在这里插入图片描述在这里插入图片描述
什么是沙箱?

Java安全模型的核心就是Java沙箱(sandbox),沙箱是一个限制程序运行的环境。沙箱机制就是将 Java 代码限定在虚拟机(JVM)特定的运行范围中,并且严格限制代码对本地系统资源访问,通过这样的措施来保证对代码的有效隔离,防止对本地系统造成破坏。沙箱主要限制系统资源访问,那系统资源包括——CPU、内存、文件系统、网络。不同级别的沙箱对这些资源访问的限制也可以不一样。
  在这里插入图片描述

3. 本地方法栈

native关键字主要用于方法上

  1. 一个native方法就是一个Java调用非Java代码的接口。一个native方法是指该方法的实现由非Java语言实现,比如用C或C++实现。
  2. 在定义一个native方法时,并不提供实现体(比较像定义一个Java Interface),因为其实现体是由非Java语言在外面实现的

4. 程序计数器

在这里插入图片描述

5. 方法区

在这里插入图片描述

6. 栈

栈管运行,堆管存储
JVM栈中的 栈针 = Java中的方法(函数)在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

深度调用后,撑爆了栈,是一个错误,不是异常
Exception in thread java.lang.StackOverflowError

java.lang.Object
	——java.lang.Throwable
		——java.lang.Error
			——java.lang.VirtualMachineError
				——java.lang.StackOverflowError

在这里插入图片描述

7. 堆

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

在这里插入图片描述

1. 堆在物理上分为两部分:新生区+养老区

2. 幸存者0区,别名S0区 (from区)
   幸存者1区,别名S1区 (to区)

3. from区和 to区是有交换的(非固定的);每次GC后会交换,谁空,谁就是to区 

在这里插入图片描述

7. 堆参数调优

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

IDEA中的run栏设置VM Options为:
-Xms1024m -Xmx1024m   -XX:+PrintGCDetails
 
import java.util.Random;
/**
 *  -Xms1024m -Xmx1024m   -XX:+PrintGCDetails
	堆初始化内存,堆最大内存    打印出堆GC回收信息
 */
public class HeapSpaceTest {
 
	
	public static void main(String[] args) {
		
		/**
		 *    输出:	MAX_MEMERY = 1808269312(字节)1724.5MB
				TOTAL_MEMERY = 122683392(字节)117.0MB
		 * @param args
		 */
//		long maxMemory = Runtime.getRuntime().maxMemory();//返回Java虚拟机试图使用的最大内存量
//		long totalMemory = Runtime.getRuntime().totalMemory();//返回当前使用的java虚拟机的内存总量
//		System.out.println("MAX_MEMERY = " + maxMemory +"(字节)" + (maxMemory/(double)1024/1024) + "MB");
//		System.out.println("TOTAL_MEMERY = " + totalMemory +"(字节)" + (totalMemory/(double)1024/1024) + "MB");
		
		
		//-Xms8m -Xmx8m   -XX:+PrintGCDetails
		String str = "www.shiye";
		while(true) {
			str += str + new Random().nextInt(9999);
		}
		/**
		 * 结果: Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
		 */
	}
}

在这里插入图片描述

package com.shi.jvm;
 
public class HeapTest {
 
	public static void main(String[] args) {
		
		/**
		 *   堆内存异常
		 *    输出结果:当前最大可用内存多少M : 1724
		* 	Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
		* 	at com.shi.jvm.HeapTest.main(HeapTest.java:8)
		*/
		System.out.println("当前最大可用内存多少M : "+Runtime.getRuntime().maxMemory()/1024/1024);
		//创建一个大对象
		byte[] b = new byte[1*1024*1024*1725];
		System.out.println("大对象创建成功");
	}
 
}

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

8. GC(分代收集算法)

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

因为Old区占Heap的2/3,比Young区更大,所以扫描更慢,即Full GC更慢

在这里插入图片描述
①引用计数算法
在这里插入图片描述
②复制算法:年轻代中使用的是Minor GC,这种GC算法采用的是复制算法
在这里插入图片描述
复制算法过程

  • GC开始的时候,对象之存在于Eden区和名为From的Survivor区,Survivor区中的To区是空的。
  • 紧接着进行GC,Eden区中所有存活的对象都会被复制到To区;From区中年龄达到阈值的对象会被移动到老年区,未达到阈值的对象会被复制到To区。
  • 经过此次GC,Eden区和From区都被清空,From区和To区交换身份,总能保证To区为空。
  • 当To区被填满,所有对象移动到老年区中。

在这里插入图片描述
在这里插入图片描述
③标记清除(Mark-Sweep)算法

  • 老年代一般是由标记清除或标记清除与标记压缩的混合实现
  • 优点:不需要额外空间
  • 缺点:两次扫描,耗时严重;会产生内存碎片(内存不连续)

若可使用的内存被耗尽时,GC线程就会被触发并将程序暂停,随后将
要回收的对象标记一遍,最终统一回收这些对象,完成标记清理工作接下来便让应用程序恢复运行。
在这里插入图片描述
在这里插入图片描述
④标记压缩(Mark-Compact)算法

  • 优点:不产生内存碎片
  • 缺点:需要移动对象的成本(耗时)

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

9. JMM(Java内存模型)

JMM (Java内存模型Java Memory Model,简称JMM) 本身是一种抽象的概念并不真实存在,它描述的是一组规则或规范,通过这组规范定义了程序中各个变量(包括实例字段,静态字段和构成数组对象的元素)的访问方式。I

①JMM特征:

  • 原子性
  • 可见性
  • 有序性

volatile是Java虚拟机提供的轻量级的同步机制

  • 保证可见性
  • 不保证原子性
  • 禁止指令重排

由于JVM运行程序的实体是线程,而每个线程创建时JVM都会为其创建一个工作内存(有些地方称为栈空间),工作内存是每个线程的私有数据区域,而Java内存模型中规定所有变量都存储在主内存,主内存是共享内存区域,所有线程都可以访问,但线程对变量的操作(读取赋值等)必须在工作内存中进行,首先要将变量从主内存拷贝到的线程自己的工作内存空间,然后对变量进行操作,操作完成后再将变量写回主内存,不能直接操作主内存中的变量,各个线程中的工作内存中存储着主内存中的变量副本拷贝,因此不同的线程间无法访问对方的工作内存,线程间的通信(传值)必须通过主内存来完成,其简要访问过程如下图:
在这里插入图片描述

public class JMM {
    public static void main(String[] args) {
        MyNumber myNumber = new MyNumber();

        new Thread(()->{
            System.out.println("Come In!!");
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            myNumber.change();
            System.out.println(Thread.currentThread().getName()+":"+myNumber.number);
        },"AA").start();

        while (myNumber.number==10){

        }
        System.out.println(Thread.currentThread().getName()+":"+myNumber.number);
    }
}

class MyNumber{
    volatile int number=10;

    public void change(){
        number=1250;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值