Rhythmli's blog Rhythmli's blog
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Rhythmli

知识就是财富
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 技术文档

  • GitHub技巧

  • Nodejs

  • 博客搭建

  • CSDN迁移

    • Spring IOC
    • Ngnix 阿里云
    • 最长回文子串
    • 面试题xuexixiexue
    • 哈希集合和哈希映射的简单设计
    • leetcode2021.11.03
    • Leetcode2021.11.2
    • JUC学习
    • 869. 重新排序得到 2 的幂
    • Java自动装箱拆箱
    • 55. 跳跃游戏
    • 剑指 Offer II 085. 生成匹配的括号
    • 300. 最长递增子序列
    • Java并发编程之美 01
    • 134. 加油站
    • 139. 单词拆分
    • 岛屿类问题题解
    • 138. 复制带随机指针的链表
    • 347. 前 K 个高频元素
    • 剑指 Offer II 026. 重排链表
    • 剑指 Offer II 025. 链表中的两数相加
    • 剑指 Offer II 014. 字符串中的变位词
    • 剑指 Offer II 010. 和为 k 的子数组
    • 剑指 Offer II 009. 乘积小于 K 的子数组
    • 剑指 Offer II 008. 和大于等于 target 的最短子数组
    • 剑指 Offer II 007. 数组中和为 0 的三个数
    • 剑指 Offer II 006. 排序数组中两个数字之和
    • 剑指 Offer II 002. 二进制加法
    • 129. 求根节点到叶节点数字之和
    • 113.路径总和 II
    • leetcode18. 四数之和
    • 编译OpenCV 以及 openc_contrib 提示缺少boostdesc_bgm.i文件出错的解决
    • fork()浅学习
    • SSM 增删改查
    • springmvc helloworld
    • Spring01 hello实验
    • 树的DFS和BFS
    • leetcode——二分法
    • Halo博客搭建
    • 计算机视觉领域的一些牛人博客,超有实力的研究机构等的网站链接---转载
    • opencv+python+OpenPose姿态实时识别
    • 03.KNN算法 李航统计学习方法
    • 02.感知机 李航统计学习方法
    • 01.最小二乘法拟合 李航统计学习方法
    • Pycharm atplotlib.pyplot图像不显示解决方法
    • 论文阅读01 SVM+kNN图像分类
    • Java简单实现计算器——用数组实现栈
    • 【剑指Offer3】无重复字符的最长子串
    • 【剑指Offer5】最长回文字符串
    • TF-IDF求取文本相似度
    • JAVA_day02
    • JAVA_day01
    • 递归产生回文数
    • 中国象棋QT登录注册以及悔棋功能
    • STM32F4学习笔记(基础介绍篇)
    • leetcode_04 递归,回溯与分治
    • leetcode03_贪心算法
    • leetcode01--链表
    • leetcode_02栈
    • Docker学习入门
    • C/C++编译与链接 程序员的自我修养:链接 装载和库
    • Nginx简单学习
    • JAVA网络编程
    • JVM初步学习
      • JVM初步学习
        • 1.基础知识
        • 2.类加载器:
        • 3.双亲委派机制
        • 4.沙箱安全机制
        • 5.native关键字
        • 6.方法区
        • 7.JVM中的栈
        • 8.三种JVM
        • 9.堆 heap
        • 10.堆内存
        • 11 新生区、永久存储区、堆内存调优
        • 12.GC 引用计数法
        • 13-GC_复制算法
        • 14-标记压缩清楚算法
        • 15-总结
    • Spring简单学习
    • 标准项目格式
    • 设计模式中的几个原则
    • Redis和IDEA简单创建及增删改查
    • Mybatis快速入门01
    • Redis全程学习笔记(附带学习的视频教程)
    • QT入门学习中最基础的那些事儿
    • QT中文输出错误问题:C2001
    • OOP:面向对象编程
    • LINUX常用命令集合(待续)
    • 《C和指针》简单学习笔记
    • 二叉树,栈存储及遍历小程序
    • 数据结构简单学习笔记
    • 扑克牌
    • C++动态内存和智能指针
    • 设计模式之简单工厂模式
    • leetcode_01数组
    • 嵌入式Linux移植应用
    • LINUX 进程与线程 信号量 通信
  • 技术
  • CSDN迁移
梁山话事人
最新推荐文章2026-08-04
目录

JVM初步学习

原文链接:https://blog.csdn.net/qq_39355828/article/details/112536735 (opens new window)

# JVM初步学习

参考 https://www.bilibili.com/video/BV1iJ411d7jS?p=14

# 1.基础知识

1.JVM运行在操作系统上,包含在jre里。

jvm调优主要在堆,方法区有一小部分。

2.类是一个模板是抽象的 对象是具体的,模板只有一个,对象创建后就有不同的地址

# 2.类加载器:

作用:加载.class文件 新建的对象放在堆里面,引用地址放到栈中,其引用指向堆里面对应的对象

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YXmfLVHm-1610441850363)(C:\Users\lhh31\AppData\Roaming\Typora\typora-user-images\1610418393354.png)]

public class Solution
{
    public static void main(String[] args) {
        Solution s1=new Solution();
        Solution s2=new Solution();
        Solution s3=new Solution();
        System.out.println(s1.hashCode());
        System.out.println(s2.hashCode());
        System.out.println(s3.hashCode());
        Class<?extends Solution>as1=s1.getClass();
        ClassLoader classLoader=as1.getClassLoader();
        System.out.println(classLoader);
        System.out.println(classLoader.getParent());
        System.out.println(classLoader.getParent().getParent());
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

在这里插入图片描述

1)虚拟机自带的加载器

2)启动类(根)加载器 Bootstrap ClassLoader

3)扩展类加载器 Extension ClassLoader

4)应用程序(系统类)加载器 Application ClassLoader

# 3.双亲委派机制

检查顺序从下至上,加载顺序从上到下。

如果一个类加载器需要加载类,那么首先它会把这个类请求委派给父类加载器去完成,每一层都是如此。一直递归到顶层(启动类加载器),当父加载器无法完成这个请求时,子类才会尝试去加载。

# 4.沙箱安全机制

控制远程代码执行的权限。

# 5.native关键字

包含native关键字的方法,说明java的作用范围不到了,会去调用底层c语言的库。

会进入本地方法栈。调用本地方法接口JNI。

JNI作用:扩展java的使用,融合不同的编程语言为java所用。 最初:c、c++

它在内存区域中专门开辟了一块标记区域:native method stack,登记native方法

在最终执行的时候,通过JNI加载本地方法库中的方法

# 6.方法区

是被所有线程共享的,所有的字段和方法字节码,以及一些特殊方法,如构造函数,接口代码也在此定义,简单说,所有定义方法的信息都保存在该区域,此区域属于共享空间

存储内容:static、final、.class、常量池

# 7.JVM中的栈

一旦线程结束,栈就结束了,内存释放。无限递归调用导致栈溢出

栈:数据结构;先进后出

队列:先进先出(FIFO)

main()先执行后结束——在栈中执行

栈:又称栈内存,主管程序的运行;生命周期和线程同步;线程结束,栈内存释放,不存在垃圾回收。

栈中存放:8大基本类型+对象引用+实例方法

栈的运行原理:栈满了StackOverflowError

存储:8大基本类型 + 对象引用 + 实例的方法

在这里插入图片描述

# 8.三种JVM

  • Sun公司:HotSpot
  • BEA:JRockit
  • IBM:J9 VM

# 9.堆 heap

一个JVM只有一个堆,堆内存的大小是可以调节的

类加载器读取了类文件后,一般会把类,方法,常量,变量,保存所有引用类型的真实对象放到堆中。

垃圾回收:轻量级GC,重量级GC(Full GC)

# 10.堆内存

分为三个区域:新生区(伊甸园区Eden Space;幸存0区,幸存1区)、养老区、永久存储区。

GC垃圾回收,主要在伊甸园区和养老区

假设内存满了OOM,java.lang.OutOfMemoryError

在JDK8以后,永久存储区叫元空间

在这里插入图片描述

# 11 新生区、永久存储区、堆内存调优

  • 新生区、类的诞生和成长的地方,甚至死亡 99%的对象都是临时对象

    • 伊甸园区Eden Space:所有对象都在伊甸园区new出来的! 满了会触发轻GC
    • 幸存0区
    • 幸存1区
  • 养老区Old:新生区幸存的,杀不死的

  • GC垃圾回收主要在伊甸园区和养老区

  • 永久存储区Perm:这个区域是常驻内存的,用于存放JDK自身携带的class对象,Interface元数据,存储的是Java运行时的一些环境。这个区域不存在垃圾回收,关闭虚拟机就会释放这个区域的内存。

    -jdk1.6之前:永久代,常量池在方法区之中

    -jdk1.7:永久代,但是慢慢的退化了,去永久代,常量池在堆中

    -jdk1.8:无永久代,常量池在元空间(方法区/非堆) 一个启动类加载了大量的第三方jar包;tomcat部署了大量的应用;大量动态生成的反射类;不断地被加载,直到内存满,会导致这个区域崩溃,出现OOM,堆内存满了

    在这里插入图片描述

默认的情况下:分配的总内存 是电脑内存的1/4;而初始化的内存:1/64

long max=Runtime.getRuntime().maxMemory();//字节1024*1024*1024
        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");
1
2
3
4

在这里插入图片描述

OOM:

1)尝试扩大堆内存看结果

2)分析内存,看一下哪个地方出了问题(专业工具)

Xms1024m Xmx1024m -XX:+PrintGCDetails

在一个项目中,突然出现了OOM故障,那么该如何排除?研究为什么出错

看到代码的第几行出错,内存快照分析工具,MAT,jprofiler

一行行测试代码(不现实)

jprofiler作用:

1)分析dump内存文件,快速定位内存泄露

2)获得堆中的数据

3)获得大的对象

元空间:逻辑上存在 物理上不存在

# 12.GC 引用计数法

JVM在进行GC时,并不是对这三个区域统一回收,大部分时候,回收都是新生代。

轻GC:普通的GC

重GC:全局的GC (full GC)

引用计数器:每个对象都记录使用次数,清除使用次数为零的算法。微软,python,

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oL1tOaOV-1610441850387)(C:\Users\lhh31\AppData\Roaming\Typora\typora-user-images\1610440088907.png)]

# 13-GC_复制算法

在这里插入图片描述

谁空谁是to

1。每次GC都会将Eden活得对象移到幸存区中,一旦Eden区被GC后,就会是空的。

2.如果空的相等,就把from移动到to,

当一个对象经历了15(-XX:MaxTenuringThreshold)次GC,都还没有死,进入老年代

年轻代主要使用复制算法。

好处:没有碎片

坏处:浪费内存空间,多了一半空间是空的,极端下,对象百分百存活,操作移动复杂

3.再优化:压缩

为了防止内存碎片产生,再次扫描,向一端移动存活的对象

标记清除压缩:先标记清除几次再压缩

在这里插入图片描述

在这里插入图片描述

# 14-标记压缩清楚算法

1.扫描对象,对活着的对象标记

2.清除:对没有标记的对象进行清除

优点:不需要额外空间

缺点:两次扫描,浪费时间,会产生内存碎片。

在这里插入图片描述

# 15-总结

内存效率:复制算法>标记清除算法>标记压缩算法(时间复杂度)

内存整齐度:复制算法=标记清除算法>标记压缩算法

内存利用率:标记压缩算法=标记清除算法>复制算法

GC:分代收集算法

年轻代:存活率低,使用复制算法

老年代:区域大,存活率高 使用标记清除(内存碎片不是太多)+标记压缩 混合实现

编辑 (opens new window)
#JAVA#订阅专栏#查看详情
上次更新: 2026/08/11, 13:36:18
JAVA网络编程
Spring简单学习

← JAVA网络编程 Spring简单学习→

最近更新
01
Spring IOC
03-31
02
Git修改分支名
08-11
03
CSS给table的tbody添加滚动条
06-29
更多文章>
Theme by Vdoing | Copyright © 2019-2026 Evan Xu | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式