jvm
文章平均质量分 54
java虚拟机
进击的小王666
这个作者很懒,什么都没留下…
展开
-
启动虚拟机时可选的参数(调优)
-verbose:class输出类加载信息-verbose:gc输出gc信息-verbose:jni输出本地方法调用信息-Xms默认堆大小-Xmx最大堆大小-Xss默认栈大小-Xmn新生代大小-XX:NewRatio=n新生代与老年代比例设置-XX:SurvivorRatio新生代eden suivivor比例-XX:+HeapDumpOnOutOfMemoryError:表示当JVM发生OOM时,自动生成DUMP文件。-XX:+PrintGCDetails打印GC日志...原创 2022-03-09 20:57:32 · 337 阅读 · 0 评论 -
jvm基础大回顾
运行时数据区域线程共享:堆和方法区线程独享:虚拟机栈,本地方法栈,程序计数器对象在内存中的分布对象结构包括对象头和对象体对象在内存中定位包括直接指针和句柄池两种方法如何分配对象内存指针碰撞:内存规整,指针移动对象大小的距离即可完成分配;空闲列表:内存不规整,需要维护一个空闲列表,记录空闲的位置以及位置大小,找到合适的空间进行分配;tlab:线程本地分配缓冲,并发情况下每个线程在堆中预先分配一小块内存,哪个线程要分配内存就在其本地缓冲区分配,直到分配新的缓存区才需要同步锁定;对象回收先判原创 2022-02-15 10:25:38 · 159 阅读 · 0 评论 -
JVM连环问
1.什么情况下会发生栈内存溢出。描述栈定义,再描述为什么会溢出,再说明一下相关配置参数,OK的话可以给面试官手写是一个栈溢出的demo。栈是线程私有的,他的生命周期与线程相同,每个方法在执行的时候都会创建一个栈帧,用来存储局部变量表,操作数栈,动态链接,方法出口等信息。局部变量表又包含基本数据类型,对象引用类型如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError异常,方法递归调用产生这种结果。如果Java虚拟机栈可以动态扩展,并且扩展的动作已经尝试过,但是无法申原创 2022-02-10 20:34:41 · 96 阅读 · 0 评论 -
类加载的生命周期以及双亲委派模型(附加3种破坏方法)
加载-》验证-》准备-》解析-》初始化-》使用-》卸载解析的顺序不一定(为了满足java语言的动态绑定)类开始加载的六种情况1、使用new,读取或设置静态变量(除了被final修饰的),调用静态方法2.使用reflect包对类型进行反射调用3.类初始化前会初始化其父类4.先初始化main方法所在的类5.jdk8的接口如果有默认实现(default修饰),实现类初始化前要先初始化这个接口。6.jdk7动态语言支持,MethodHandle实例的解析结果为四种方法句柄,需要对方法句柄对应的类进行原创 2022-01-23 17:10:08 · 204 阅读 · 0 评论 -
类文件结构
代码编译的结果由本地机器码转变为字节码,这与平台无关的基石;只要是符合java虚拟机规范的字节码文件,就可以被运行。class文件的格式class文件是一组以8个字节为基础单位的二进制流,排列紧凑而没有分隔符;采用类似c语言伪结构体的方式存储,里面包含无符号数(u1、u2、u4、u8)和表(由多个无符号数或者其他表作为数据项构成的复合数据类型)两种数据类型。头四个字节为魔数,作用是确定这个文件可以被虚拟机接受,接下来的四个字节存储了class文件的版本号,具有向下兼容的特性(顺序是次版本号+主版本原创 2022-01-23 15:17:00 · 451 阅读 · 0 评论 -
经典的垃圾收集器(CMS&G1为重点)
垃圾收集器⭐新生代都采用标记复制算法Serial(串行):单线程工作(STW)Parnew:多线程并行版本(并行是指多个垃圾收集线程一起工作,适用多核)Parallel Scavenge收集器:同样的并行收集器,关注吞吐量,并且可以设立目标自适应调节(重要)老年代大都采用标记整理算法(除了CMS采用标记清除)Serial old:单线程(STW),一个作用是与Parallel Scavenge搭配使用(一度导致Parallel Scavenge地位尴尬),另一个作用是CMS并发收集发生Concu原创 2022-01-23 11:34:01 · 239 阅读 · 0 评论 -
jvm垃圾收集算法的实现细节
算法实现细节根节点枚举必须stw(停止用户线程),必须在一个能保持一致性的快照中进行具体实现有oopmap(避免全栈扫描,已经存储了哪些是reference)安全点与安全区只在特殊指令产生或更新oopmap,否则效率低定义:能让程序长时间执行->字节码指令序列复用(方法调用,循环跳转,异常跳转)为了保证所有线程都停在安全点,有两种方案;抢先式中断将所有线程中断然后将未到安全点的线程恢复直至到达安全点主动式中断设置标志位,各个线程不停轮询此标志位,发现中断标准为真时原创 2022-01-22 17:16:50 · 441 阅读 · 0 评论 -
方法区中的回收
方法区中回收的对象包括两部分,不被引用的常量以及不被使用的类型。已经没有任何字符串对象引用常量池中的“java”常量,且虚拟机中也没有其他地方引用这个字面量。如果在这时发生内存回收,而且垃圾收集器判断确有必要的话,这个“java”常量就将会被系统清理出常量池。判定一个类型是否属于“不再被使用的类”的条件就比较苛刻了。需要同时满足下面三个条件:·该类所有的实例都已经被回收,也就是Java堆中不存在该类及其任何派生子类的实例。·加载该类的类加载器已经被回收,这个条件除非是经过精心设计的可替换类加原创 2022-01-22 12:04:08 · 480 阅读 · 0 评论 -
jvm判断对象死亡的方法以及四种引用关系
判断对象生死的两者方法引用计数法每个对象添加一个引用计数器,有对象引用他,计数器加一,引用失效,计数器减1,互相引用导致不能被回收。可达性分析通过一系列被称为GC root的根对象作为起始节点集,从这些节点开始,根据引用关系向下搜索,搜索过程中走过的路径被称为引用链, 如果某个对象到GC root间没有任何引用链相连接,在有向图中表示GC root到这个对象不可达,此对象不可能再被使用。GC Roots的对象包含:在虚拟机栈中引用的对象,方法区中类静态属性引用的变量,原创 2022-01-22 11:36:56 · 121 阅读 · 0 评论 -
OOM(OutOfMemoryError异常实战)
堆溢出Java堆用于储存对象实例,我们只要不断地创建对象,并且保证GC Roots到对象之间有可达路径来避免垃圾回收机制清除这些对象,那么随着对象数量的增加,总容量触及最大堆的容量限制后就会产生内存溢出异常。在运行期我设置了-Xms20m -Xmx20m 使得堆内存不可扩展,否则等待时间比较长。public class Stack666777 { static class OOMObject { } public static void main(String[] args)原创 2022-01-21 21:31:03 · 866 阅读 · 0 评论 -
java对象在内存中的结构以及对象访问定位形式
对象在内存中的结构对象头markword(存储对象自身的运行时数据,如哈 希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等)指向类型元数据的指针,如果是数组,还需要有长度信息(普通对象的大小编译时已经确定,数组类型必须记录长度)实例数据对齐填充(java虚拟机要求对象起始地址为8字节的整数倍,弥补实例数据部分的不足)对象访问定位形式句柄在java堆中划分出一块内存来作为句柄池,reference中存储着对象的句柄地址,句柄中又分别记录原创 2022-01-21 20:34:07 · 120 阅读 · 0 评论 -
java对象创建过程
对象的创建大概分为以下几步:1:检查类是否已经被加载;2:为对象分配内存空间;3:为对象字段设置零值;4:设置对象头;5:执行构造方法。详细说明:遇到new指令,检查这个指令的参数能否在常量池定位到符号引用,并检查是否加载、解析、初始化过,如无,先进行类的加载。接下来进行对象内存分配,(这块内存在类加载后即可确定大小)* 指针碰撞使用过的在一边,空闲内存另外一边,中间是一个指针作为分界点的指示器,挪动对象大小的距离即可。* 空闲列表内存不是规整的,需要维护一个列表从列表中找到一块足够原创 2022-01-21 20:01:03 · 322 阅读 · 0 评论 -
jvm运行时数据区域(内存模型)
首先要明确的两个概念:内存区域是指 Jvm 运行时将数据分区域存储,强调对内存空间的划分。而内存模型(Java Memory Model,简称 JMM )是定义了线程和主内存之间的抽象关系我们平时谈到的内存划分大都倾向于关注内存区域。这个图可以很好的描述这种关系。可以看到,虚拟机栈,本地方法栈和程序计数器由线程私有,而堆和元空间由线程共有(jdk1.8后方法区由元空间实现)Java 8 中 PermGen(永久代) 为什么被移出 HotSpot JVM 了?在1.7的时候将字符串常原创 2022-01-21 14:27:04 · 727 阅读 · 0 评论