![](https://img-blog.csdnimg.cn/20201014180756928.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
JVM
该换键盘了
这个作者很懒,什么都没留下…
展开
-
synchronized关键字与JUC中Lock的区别,CAS操作及ABA问题
synchronizedsynchronized关键字在javac编译之后会在同步块的前后分别形成monitorenter,monitorexit两个字节码指令。都需要reference对象来指明锁定和解锁的对象,如果没有明确指定,根据synchronized修饰的方法类型(实例方法或者类方法),来决定取代码所在的对象实例还是取类型对应的Class对象来作为线程要持有的锁。在执行monitorenter指令时,首先要尝试获取对象的锁,如果对象没有被锁定,或者当前线程已经持有了那个对象的锁,就把锁的计数器原创 2020-10-29 09:43:06 · 391 阅读 · 8 评论 -
Java内存模型与虚拟机并发中的三种特性与先行先发生原则
Java内存模型(JMM)Java内存模型的主要目的是定义程序中各种变量的访问规则,即关注在虚拟机中把变量值存储到内存和从内存中取出变量值这样的底层细节。此处的变量包括了实例字段,静态字段和构成数组对象的元素,但是不包括局部变量与方法参数,因为后者是线程私有的,不会被共享。Java内存模型规定了所有的变量都存储在主存中,是虚拟机内存的一部分。每条线程还有自己的工作内存,线程的工作内存中保存了被该线程使用的变量的主内存副本,线程对变量的所有操作(读取,赋值等)都必须在工作内存中进行,而不能直接写主存中的数原创 2020-10-29 08:48:24 · 113 阅读 · 0 评论 -
虚拟机Class类的文件结构
Class类文件结构任何一个Class文件都对应着唯一的一个类或一个接口的定义信息,但是类或接口并不一定都要定义在文件里(动态生成)。Class文件是一组以8个字节为基础单位的二进制流,Class文件采用类似于C语言结构体的伪结构体来存储数据,这种结构体只有两种数据类型:“无符号数”和“表”。无符号数:以u1,u2,u4,u8来分别代表1个字节,2个字节,4个字节,8个字节的无符号数,无符号数可以用来描述数字,索引引用,数量值或者按照UTF-8编码的字符串。表:表是由多个无符号数或者其他表作为数据项原创 2020-10-28 20:37:53 · 103 阅读 · 0 评论 -
在idea配置虚拟机参数与虚拟机内存溢出
Java堆溢出Java堆用于存储对象的实例,如果对象的数量增加到堆的最大容量就会产生内存溢出现象。堆得最小值**-Xms**,堆的最大值**-Xmx** static class OOMObject { } public static void main(String[] args) { List<OOMObject> list = new ArrayList<>(); while (true)原创 2020-10-28 13:18:31 · 1061 阅读 · 2 评论 -
虚拟机内存分配与回收策略(十二)
在经典分代的设计下,新生对象通常会分配在新生代中,少数情况(对象大小超过阈值)也可能直接分配在老年代。对象优先在Eden分配多数情况,对象会在新生代Eden区分配,当Eden区没有足够的空间时虚拟机会发起一次Minor GC。-XX:+PrintGCDetails,告诉虚拟机发生垃圾回收的时打印内存回收日志,并且在进程退出的时候输出当前内存各区域分配情况。-XX:SurvivorRatio=8决定了新生代Eden区与一个Survivor区的空间比为8:1。例:当新生代中Eden区为8M时两个Su原创 2020-10-27 21:14:12 · 155 阅读 · 0 评论 -
类加载器至双亲委派模型(十一)
类加载器Java虚拟机设计团队有意把类加载阶段中的“通过一个类的全限定名来获取描述该类的二进制字节流”这个动作放到Java虚拟机外部去实现,以便让应用程序自己去决定如何获取所需的类,实现这个动作的代码叫做“”类加载器“”。对于任意一个类,都必须由类和类加载器共同确立其在Java虚拟机中的唯一性,每一个类加载器都有一个独立的命名空间。通俗的表达:比较两个类是否“相等”,只有在这两个类是由同一个类加载器加载时才有意义,即使来自同一个Class文件,被同一个虚拟机加载,只要加载它们的类加载器不同,那么这两个原创 2020-10-27 15:42:01 · 148 阅读 · 0 评论 -
类加载过程之初始化(十)
初始化类的初始化是类加载的最后一个步骤,在准备阶段时类中的变量都为系统规定的初始值,在初始化阶段会根据程序来进行。更直接的表达:初始化阶段就是执行类构造器< clinit >()方法过程。< clinit >()方法的产生:是由编译器自动收集类中的所有类变量的赋值动作和静态语句块(static{}块)中的语句合并产生的。编译器收集顺序是由语句在源文件中出现的顺序决定的,静态语句块中只能访问到定义在静态语句块之前的变量,定义在它之后的变量,在前面的静态语句块可以赋值,但是不能访原创 2020-10-26 23:13:13 · 155 阅读 · 0 评论 -
类的加载过程值准备与解析(九)
准备阶段准备阶段是正式为类中定义的变量(静态变量,被static修饰的变量)分配内存并设置类变量初始值的阶段,不包括实例变量。public static int value = 123;此时只会将value赋值为初始值0.真正赋值为123是在类构造器 < clinit>() 方法中。public static final int value = 123;准备阶段就会将value赋值为123解析解析阶段是Java虚拟机将常量池内的符号引用替换为直接引用的过程。符号引用符号引原创 2020-10-26 19:52:41 · 147 阅读 · 0 评论 -
类加载的过程之加载与验证(八)
类加载全过程:加载,验证,准备,解析,初始化。加载阶段在此阶段,虚拟机要完程三件事:通过一个类的全限定名来获取定义此类的二进制字节流。将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。在内存中生成一个代表这个类 java.lang.Class 对象,作为方法区这个类的各种数据的访问入口。加载阶段既可以使用Java虚拟机里内置的类加载器来完成,也可以由用户自定义的类加载器去完成。对于数组来说,数组类不有类加载器创建,它由Java虚拟机直接在内存中动态构造出来,但是数组的元素类型原创 2020-10-25 23:54:25 · 318 阅读 · 2 评论 -
Java虚拟机类加载机制(七)
类加载机制什么是类加载机制?Java虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验,转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型。每个Class文件代表着一个类或者接口。...原创 2020-10-25 16:55:12 · 59 阅读 · 0 评论 -
JVM对象的内存布局与对象的访问定位(六)
内存布局对象在堆中可以划分为三个部分:对象头,实例数据,对齐填充1. 对象头HotSpot虚拟机对象头包含两类信息,一类用于存储对象自身的运行时数据,如哈希码,GC分代年龄,锁状态标志,线程持有的锁等。这部分的长度在32位和64位虚拟机中分别占32比特和64比特,官方称为**“Mark Word”**。在32个比特空间中25个比特用来存储哈希码,4个比特用于存储对象分代年龄,2个比特用于存储锁标志位,1个比特固定为0。**另一部分:**类型指针,指向它类型元数据的指针,通过指针来判断该对象是哪个类原创 2020-10-25 09:59:13 · 88 阅读 · 0 评论 -
JVM垃圾回收的三种算法(五)
标记-清除算法(最基础)算法分为:“标记”,“清除”两个阶段,首先标记处所有需要回收的对象,在标记完成后,统一回收掉所有被标记的对象,也可以标记存活的对象,统一回收未被标记的对象。缺点:执行效率不稳定,如果Java堆中包含大量对象,而且其中大部分是需要被回收的,就必须进行大量的标记和清除动作,造成标记和清除两个过程执行效率都随对象的增多而降低。内存碎片化,标记,清除之后会产生大量不连续的内存碎片,空间碎片过多会导致程序运行中如果需要分配较大空间是无法找到足够的连续的内存空间而不得不提前触发一次垃圾原创 2020-10-24 16:06:57 · 104 阅读 · 0 评论 -
JVM分代理论(四)
从如何判定对象消亡的角度出发,垃圾收集算法可以划分为**“引用计数式垃圾收集”和“追踪式垃圾收集”**,也被称为“直接垃圾收集”和“间接垃圾收集”。以下介绍的都为“间接垃圾收集”。分代收集理论建立在两个分代收集假说上:弱分代假说:绝大多数对象都是朝生夕灭的强分代假说:熬过越多次垃圾收集过程的对象就越难以消亡。收集器将Java堆划分出不同的区域,将回收对象依据年龄(熬过回收的次数)分配到不同的区域中储存。原因是:这样虚拟机可以使用较低的频率来回收这个区域,兼顾了垃圾收集的时间开销和内存空间的有效原创 2020-10-24 14:02:36 · 183 阅读 · 0 评论 -
JVM虚拟机如何判断对象死亡?(三)
JVM中的程序计数器,本地方法栈,虚拟机栈都为线程私有,随线程的产生而产生,消亡而消亡,这几个区域的内存分配和回收有确定性,而在Java堆和方法区中内存的回收具有不确定性,只有在运行期间才知道要去创建多少个对象,内存的分配和回收是动态的。堆中存放着Java几乎所有的对象,垃圾收集器在对堆进行回收时,首先要确定堆中哪些对象还存活,那些对象已死去(没有任何用途的对象)。判断对象是存活引用计数法在对象中添加一个引用计数器,每当有一个地方引用它时,计数器就加一;当引用失效时,计数器的值就减一,任何时刻计数器原创 2020-10-23 14:41:09 · 132 阅读 · 3 评论 -
JVM对象创建过程 (二)
**对象的创建**当java虚拟机遇到一条字节码new指令时,首先检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并检查这个符号引用代表的类是否已被加载,解析和初始化过。如果没有就必须先执行相应的类的加载过程。类加载过程通过后,虚拟机将为新生对象分配内存。对象所需内存在类加载后就完全可以确定,为对象分配空间相当于把一块确定大小的内存从Java堆中划分出来。假设Java堆中的内存是绝对规整的,所有使用过的内存放到一边,空闲的内存放到另一边,中间放着一个指针作为分界点的指示器,分配内存相当于原创 2020-10-21 17:52:39 · 65 阅读 · 0 评论 -
JVM虚拟机之虚拟机区域划分及包含内容(一)
运行时的数据区域Java虚拟机在执行Java程序是会将所管理的内存分为若干个区域方法区与堆区为线程共享数据区,虚拟机栈,本地方法栈,程序计数器为线程私有。程序计数器程序计数器是一块较小的内存空间。可以看做是当前线程所执行的字节码的行号指示器。字节码解释器通过改变计数器的数值来选取下一条需要执行的字节码指令。多线程时,每个线程都有一个独立的程序计数器,每个计数器之间互不影响。如果线程正在执行一个Java方法,计数器记录的是正在执行的虚拟机字节码指令的地址。当执行本地方法时,计数器为空(Undefi原创 2020-10-16 22:27:38 · 412 阅读 · 0 评论