jvm虚拟机知识点

本文详细介绍了Java虚拟机(JVM)的工作原理,包括运行数据区的各个部分,如程序计数器、虚拟机栈、本地方法栈、方法区和堆。讲解了方法区与堆的区别,以及为何不合并存储数据。同时,阐述了对象的创建过程、内存溢出问题以及垃圾回收算法,如复制算法、标记-清除算法和CMS并发标记扫描。此外,还涉及了各种引用类型以及垃圾回收器的选择,如Serial、Parallel和CMS。
摘要由CSDN通过智能技术生成

Jvm 的工作相当于翻译   将java.class 转化成各个平台能识别的机器码

JVM运行过程

 

运行数据区也就是jvm所管理的内存区域     里面包含程序计数器  虚拟机栈  本地方法栈  方法区 以及堆

方法区:.class 类信息  静态变量  常量

Jdk 1.7  永久代

Jdk1.8  元空间  好处:方便拓展(使用机器内存)   坏处:机器内存总共20g 元空间15g,那么堆空间 只能5g的了 ,压缩堆空间

堆: 对象存放的地方 (几乎所有)  数组

方法区以及堆 两个地方存东西  为什么步合并成一个地方存数据?

因为堆里面的信息  频繁回收创建

方法区  里面的信息 基本不会被回收掉

程序计数器 :相当于指针的含义     指向正在运行字节码行数  

为什么需要程序计数器 ?

因为时间片轮转机制   被挂起之后 在次获得cpu的时候知道上次执行到哪里  

作为jvm内存区域唯一不会oom的内存区域  程序计数器 以为程序计数器只需要个Int类型的内存空间就可以的

虚拟机栈 (java栈) 先进后出  后进先出

栈帧

局部变量表  八大基础数据类型

操作数栈    执行每一行代码的操作

动态链接

完成出口     main 方法中  执行work方法执行完之后    在main的栈帧中存放work返回的数据

知识点补充:

八大基本类型    字符类型  char   布尔类型  boolean

                数值类型   整数类型   int  short  long  byte

                           浮点类型   float  double

基本类型和包装类的区别

Int 是个基本的数据类型  Interge 是一个类   使用的时候 要进行初始化  int就不用初始化

Jvm是  栈操作   这里的在栈指的栈帧里面的操作数栈   不是指的虚拟机栈  优缺点: 兼容性好  效率低  因为要频繁的进栈出栈操作

Android 或是 c  是 寄存器操作  操作步骤少   相当于把栈中的局部变量表和操作数据融合在一次   减少操作步骤    优缺点 : 操作速度快    可移植性差

本地方法栈:

本地方法栈 保存的是native本地方法 c++执行的操作

从数据共享以及私有的角度考虑

  1. 程序计数器  虚拟机栈  本地方法栈 属于线程私有的数据区(线程隔离数据区)这个相当于个套餐   启动个线程  每个线程就会有 三个数据区
  2. 方法区和堆  是共享数据区

查看当前多有的java进程    cmd里面 打jps

内存溢出:

  1. 栈溢出  stackoverflow  栈内存溢出    还有一种情况是 一个线程起一个虚拟机栈(默认占1m) 如果机器只有500m  启动1000个线程 的话 那么也会包oom  栈溢出
  2. 堆溢出  超过堆的内存
  3. 方法区内存溢出
  4. 本机直接溢出

虚拟机优化技术

方法内联   实现同样的功能    尽量代码简洁

栈帧之间数据共享

虚拟机中对象创建过程

 

检查加载:检查这个类有没有

分配内存 :用下面的那个方法取决于 垃圾回收器方法   带不带整理功能

指针碰撞: 堆空间比较规整时候

空闲列表: 垃圾回收之后  内存空间不规整

并发的问题 :CAS 浪费性能   本地线程分配缓冲 TLAB  占E等区的1%

内存空间初始化:对象的参数进行 零值操作

设置 :设置对象属于那个类  对象头

 

对象的 是由对象头+实例数据 +对齐填充    凑够8字节的整数倍

如何判断对象是否存货

  1. 引用计数算法   
  2. 可达性分析法

 

Object  里面的Finalize 可以进行对象自救   只能执行一次  线程级别很低,可控性不高

Java中各种引用

软引用:当内存空间要发生oom的时候 对象就会被回收 使用场景:图片缓存 或是网页缓存

弱引用:发生了gc 不管内存够用不够用  直接回收了

虚引用:监控垃圾回收器 是否正常工作

软引用和弱引用对比    建议还是用弱引用  因为软引用是要发生oom的时候 才回收  假如说 还剩100m空间   软引用20m 强引用100m 哪怕是软引用回收了  也会引起oom的,弱引用基本不会出现这个问题  因为要发生oom  之前一定进行了多次的gc, 这样的话,多次回收之后  空间就有可能够用了   

Oom异常的时候  catch里面不用Exezipation   而是要用  throwable (可抛出 异常)

逃逸分析 指的是  对象作用域   只在栈帧里面应用  不被外面所调用 。如被外面调用的话  方法逃逸   能被外部线程赋值  线程逃逸  就是逃逸成功   就不能栈上分配   

  1. 绝大多数的对象都是朝生夕死  98%死  新生代   eden from to  8:1:1
  2. 对象熬过多次垃圾回收,越来越难回收  老年代 Tenured

Jvm中 新生代和老年代所占空间比例   1/3  2/3 也就是 1:2

复制算法适用在新生代

为什么增加eden区   增加空间利用率   正常的复制算法 一半存放对象,一般做预留操作,这样的利用率只有50%的  增加eden区的话  复制算法只在from和to区进行执行eden from to  的比例为8:1:1  那么利用率就是90%

这个算法适合老年代  不适合新生代    因为新生代98%的对象都要回收  标记就要标记90% 标记多了也费性能,得不偿失   老年代基本是难回收的对象  所以适合

 

Serial 串行   单线程

Parallel 并行  多线程并行

Concurrent 并发 cms中的c 多线程并发

Serialold  可以和 新生代 serial parnew parallel 回收器搭配使用

Cms 可以和新生代  serial parnew  以及老年代的 serialold 搭配使用

Parallelold 只能和新生代的parallel 一起使用   

并行 :启用多个线程 多个垃圾回收器一起工作 但是用户线程要全部停止

    并发: 启用多个线程 多个垃圾回收器线程可以和用户线程一起工作

 

  Serial 单线程垃圾回收器 和并行paralell多线程垃圾回收器都要 暂停所有用户线程 stop the word   这样会影响用户体验

CMS  concurretn  并发  

   标记清除算法 两个步骤 第一步是  标记 第二部是清除

   Cms 就是在这两个地方进行优化

   拆分标记  初始标记: 只标记根可达的对象  根可达对象少 花费时间少  

             并发标记: 开启线程  对上面根可达对象的下面的对象 进行标记操作,这块耗时              

重新标记 :因为标记线程和用户线程一起运行所以会有遗漏的没有标记,所以要重新标记

  清除操作:并发清除-----》重置线程   --》用户线程

 Cms的优点: 减少暂停用户线程的时间,提高用户体验感 不卡顿

       缺点: 1.cpu敏感  占用一个cpu做垃圾回收,用户线程减少,增加用户线程负担

              2.浮动垃圾  在并行清理时候出现的垃圾只能下次在进行清除  浮动垃圾过多的时候  马上要oom的时候  会使用serialold垃圾回收器

              3.内存碎片  因为cms采用的是标记清除的算法所以会产生内存碎片

G1的理解  :不在划分老年代和新生代   将内存等分  eden survivor old humongous(大对象  (定义:超过平分的内存就是大对象))

处理方式和cms类似  初始标记 并发标记 重新标记

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值