JVM(初级)- 笔记

JVM笔记篇

本文描述基于jdk1.8

一、JVM概述和分类
1,JVM的概述
在这里插入图片描述
2,JVM的分类
JVM有三种(SUN(HotSpot)、BEA、IBM),通常使用的第一种

二、JVM内存结构
在这里插入图片描述1,线程共享
1.1 堆
JVM 所管理的内存中最大的一块
存放new的对象和数组
存在垃圾回收(GC机制)

1.2 方法区(存在元数据区):类信息太多会内存溢出
静态变量,常量;类,方法,属性修饰信息(public class Xxx,private void xxx(){})

2,线程私有
2.1 栈:栈内存溢出 --StackOverflowError
先进后出
与线程生命周期相同,线程结束栈内存就释放,不存在垃圾回收的问题
存储:局部变量,对象

2.2 本地方法栈
private native void start0();
方法体由C/C++实现

2.3 程序计数器
每个线程都有一个程序计数器,是线程私有的,就是一个指针,指向方法 区中的方法字节码(用来存储指向像一条指令的地址,也即将要执行的指令代码)在执行引擎读取下一条指令,是一个非常小的内存空间,可以忽略不计。

判断线程共享还是线程私有

package com.smallegg;

public class Test {
    public static void main(String[] args) {
        Wzl wzl=new Wzl();
        new Thread(wzl).start();
        new Thread(wzl).start();
        new Thread(wzl).start();
        new Thread(new Wzl()).start();
        new Thread(new Wzl()).start();
        new Thread(new Wzl()).start();
        new Thread(new Wzl()).start();
    }
}

class Wzl implements Runnable{

    @Override
    public void run() {
        int[] a={1,2,3,4,5,6,7,7};
        System.out.println(++a[0]);
    }
}
package com.smallegg;

public class Test {
    public static void main(String[] args) {
        Wzl wzl=new Wzl();
        new Thread(wzl).start();
        new Thread(wzl).start();
        new Thread(wzl).start();
        new Thread(new Wzl()).start();
        new Thread(new Wzl()).start();
        new Thread(new Wzl()).start();
    }
}

class Wzl implements Runnable{
	@Override
    public void run() {
        int[] a=3;
        System.out.println(++a);
    }
}

三、类加载器:加载-链接-初始化
加载:
1,Bootstrap ClassLoader(启动类装载器,C/C++开发)
负责加载JRE的核心类库,如lib下的rt.jar,charsets.jar等
2,Extension ClassLoader(扩展类装载器)
主要加载JAVA_HOME/lib/ext目录中的类库
3,Application ClassLoader(应用程序类装载器)
负责加载用户路径ClassPath路径下的类包
4,User ClassLoader(用户自定义类装载器)
负责加载用户自定义路径下的类包
链接:
1,验证类的信息,是否有安全问题
2,为类变量(static)分配内存并设置默认值,发生在方法区
3,虚拟机常量池的符号引用替换为直接引用(地址)的过程
初始化:

四、JVM的特性
1,双亲委派机制:参考三加载部分
加载类…如果JDK提供的类存在,已JDK提供的类信息为主(通常包名可以区分)
2,沙箱安全机制

五、GC(STW -stop the world)
1,概述:
垃圾回收(存在于堆区)

2,堆内存
年轻代:
eden:from:to = 8:1:1
老年代:
经历15次GC仍存活的对象
元数据区(永久代):
永久区是JDK1.8及之前说法,和元数据区的区别是存储的位置

3,GC --发生在JVM中的堆和方法区
什么是垃圾
没有引用指向的一个或多个对象叫做垃圾

垃圾怎么找到
引用计数
有一个引用指向一个对象,计数就加1 ,直到这个数为0,就会被当作垃圾(无法解决循环引用,需要额外内存计数,运行期间需要维护计数器,带来额外的开销)
根可达算法
GCRoot(GC Roots就是对象,而且是JVM确定当前绝对不能被回收的对象(如方法区中类静态属性引用的对象 )。
只有找到这种对象,后面的搜寻过程才有意义,不能被回收的对象所依赖的其他对象肯定也不能回收)
通过一系列被称为「GC Roots」的根对象作为起始节点集,从这些节点开始,通过引用关系向下搜寻,搜寻走过的路径称为「引用链」,如果某个对象到GC Roots没有任何引用链相连,就说明该对象不可达,即可以被回收。

原文链接

垃圾找到的处理方案
标记-清除
先遍历一遍,给需要清除的对象标记上,再把标记的对象都清除。(存在的问题:内存空间不连续,如果过大的对象,需要额外开辟空间,造成空间资源的浪费)

复制算法
空间一分为2,存对象的那一半满了,触发GC,开始循环一遍,把GC存活的对象克隆到另一半区域,然后把这半区域整体清除(缺点显而易见,空间利用率不高)

标记-清除-整理
与标记清除一样,但是GC之后存活的对象挪位,把碎片空间给聚集在一起(不足:效率)

分代收集算法
所谓分代收集算法就是把堆区分为:
年轻代,老年代
演变:
年轻代细分:eden,survivor0,survivor1
伊甸园区,幸存0区,幸存1区(幸存区会互相转换,所以也叫from to区)
目前理解:
两个幸存区有一个需要为空,一次GC之后存活的对象存在那片空幸存区,因为采用的是复制算法,没有内存碎片产生。GC15次还存活下来的对象克隆到老年区

老年代:
老年代内存不足时,触发full GC(GC)
触发标记整理(次数少)

GC算法参考链接:
GC算法通俗易懂

方法区如何进行内存回收?
回收的对象:废弃常量和无用的类
1、废弃常量
与回收Java堆中对象非常类似;
2、无用的类
同时满足下面3个条件才能算”无用的类”:
1)该类所有实例都已经被回收(即Java椎中不存在该类的任何实例);
2)加载该类的ClassLoader已经被回收,也即通过引导程序加载器加载的类不能被回收;
3)该类对应的java.lang.Class对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法;

此处参考链接:
内存判断

六、代码及工具的使用
1,触发堆内存溢出
2,参数配置,控制台打印
3,参数配置,dump文件
4,JProfiler,断点排错

JMM

推荐视频:
B站,遇见狂神说,对新手很友好,此文大部分为看他视频的笔记

本文存在的错误及可优化的观点,还望指出

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码style

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值