
JVM学习笔记
文章平均质量分 81
JVM基本原理与调优
程光CS
Auf dem Wasser zu singen, Op.72, D.774 - Auf dem Wasser zu singen, Op.72, D.774
展开
-
JVM笔记 —— 出现内存溢出错误时时如何排查
内存溢出错误分为StackOverflowError和OutOfMemoryError,前者是栈中出现溢出,后者一般是堆或方法区出现溢出,简称OOM### 1. 栈溢出 StackOverflowError栈溢出一般都是因为没有正确的结束递归导致的,无限递归导致超出栈内存(-Xss)限制时就会抛出StackOverflowError。这种情况直接根据异常信息定位到代码位置进行修正即可。2. 方法区溢出 OOM当方法区中加载的类过多,比如通过**动态代理生成很多代理类**或者**热部署时热加载了过多的原创 2023-08-10 17:02:04 · 1628 阅读 · 0 评论 -
JVM笔记 —— 垃圾回收(GC)详解
严格来说,如果某些对象在程序中不会再被用到了,但是这些对象又无法被垃圾收集器回收(GC Roots以及其引用链可达的强引用对象),那么这些对象所占用的内存就处于平白浪费的状态了,这就的内存泄漏。如果这种情况可以累积,随着内存泄漏的增多,就会导致严重的性能问题甚至OOM。宽泛地说,实际情况中很多时候一些不太好的实践会导致对象的生命周期变得过长,比如不合理地进入了老年代,在老年代中堆积,等到Full GC时才能被回收,这种情况也可以叫“内存泄漏”。原创 2023-04-22 21:16:51 · 2544 阅读 · 0 评论 -
JVM笔记(8)—— 直接内存
直接内存不是虚拟机运行时数据区的一部分,是在运行时数据区外、直接向系统申请的内存空间。通常,访问直接内存的速度会优于堆,读写性能更好。因此,出于性能考虑,读写频繁的场合可能会考虑使用直接内存。Java的NIO库允许Java程序使用直接内存,用于数据缓冲区。普通IO写需要从用户缓存空间copy到内核缓存空间再copy到磁盘(读就是反过来),而NIO是直接与磁盘进行交互,因此速率更快,适合对大文件的读写操作。原创 2023-02-23 21:04:24 · 1065 阅读 · 0 评论 -
JVM笔记(7)—— Java对象创建的过程
一、Java对象的创建有六种方式:1.new关键字 2.Class对象的newInstance()方法 3.Constructor对象的newInstance()方法 4.对象的clone()方法 5.反序列化 6.其他第三方库。二、对象的创建有六个步骤:1.判断对象所属类是否加载 2.给对象分配内存空间 3.处理并发安全问题 4.初始化分配到的空间 5.设置对象的对象头 6.执行init方法完成初始化。三、堆中的一个对象包括:对象头(运行时元数据markword、类型指针)、实例数据、对齐填充原创 2023-02-22 20:41:49 · 712 阅读 · 0 评论 -
JVM笔记(6)—— JVM运行时问题案例
用jdk提供的命令jstack查看进程号对应jvm进程中所有线程的运行情况,并通过线程id (转换为16进制)找到有问题的线程,进一步定位到问题代码的源码行号。排查:可能是由于多个线程发生了死锁,用jstack 进程id查看jvm进程信息,若发现有死锁,则会在最后输出相应信息,据此定位到具体源码行号。根据进程id用ps命令进一步定位是哪个线程引起的cpu占用过高:ps H -eo pid,tid,%cpu | grep 进程id。用top命令查看哪个进程对cpu的占用过高,获取进程id。原创 2023-02-07 18:15:23 · 504 阅读 · 0 评论 -
JVM笔记(5)—— 运行时数据区—— 方法区
进程运行过程中,在方法中创建对象时通过方法区中的类型信息在堆中创建对应的对象,对象中又存有指向方法区中对应类型信息的指针,并将对象的地址引用存入虚拟机栈对应方法栈帧的局部变量表中。方法区是所有线程共享的区域,主要用于存储类加载系统加载进来的每个类的类信息,JIT即时编译器编译后的代码缓存等jdk7及以前,方法区的实现称为永久代(PermGen space),8及以后则称为元空间(Metaspace)。元空间与永久代的最大区别在于:元空间不在虚拟机设置的内存中,而是直接使用本地内存\color{red}{原创 2023-02-02 21:36:34 · 520 阅读 · 0 评论 -
JVM笔记(4)—— 运行时数据区——堆空间
为什么要对堆空间进行分代?因为不同对象的生命周期不同,绝大部分对象都是临时对象,如果不进行分代设计,那每次GC都要对所有对象进行扫描,影响GC性能,通过分代设计,大部分时候GC只需要对其中一块空间进行垃圾回收,优化了整体性能。原创 2023-01-31 21:10:53 · 623 阅读 · 1 评论 -
JVM笔记(3)—— 运行时数据区—— 程序计数器、虚拟机栈、本地方法栈
虚拟机栈是运行时的单位,而堆是存储的单位即:栈是解决程序的运行问题,即程序如何执行。而堆解决的是数据存储的问题,即数据怎么放,放在哪每个线程在创建时都会创建一个虚拟机栈,线程运行时每调用一个方法都会生成一个对应的栈帧压入栈,方法执行结束(正常return或内部抛出异常)则出栈,并将结果返回给前一个栈帧,使前一个栈帧成为当前活动栈帧,直到所有栈帧全部出栈,则线程执行结束,栈也同时销毁。虚拟机栈是线程私有的,生命周期和线程一致。原创 2022-12-29 20:37:00 · 885 阅读 · 0 评论 -
JVM笔记(2)—— 运行时数据区概述及线程
在上一篇中我们讲了JVM的,现在我们就来到了运行时数据区。而不同版本的JVM对于内存的划分方式和管理机制存在着部分差异(最典型的就是方法区实现的差异),本文针对经典的Hotspot jvm进行讨论,对运行时数据区做一个总体的概述一个JVM进程中只有一个Runtime实例,即运行时环境,就相当于运行时数据区。其中和:是线程共享的区域,整个运行时数据区中只有一份。垃圾回收主要针对的区域就是堆空间,其次是方法区:是每个线程都有一份,是各个线程私有的,原创 2022-12-01 19:39:08 · 674 阅读 · 0 评论 -
JVM笔记(1)——类加载子系统
类加载子系统负责从文件系统或网络中加载class文件,加载的类信息存放在一块称为方法区的内存空间,称为类的DNA元数据模板。程序启动时的main方法类是由AppClassLoader加载的,而类中直接引用到的类是由加载当前类的加载器先执行loadClass的,类中指定加载器加载的类则是由指定加载器先loadClass的,由此我们就可以推出程序中每个类的加载流程原创 2022-11-23 22:46:39 · 662 阅读 · 0 评论