Java虚拟机内存模型(Java运行在虚拟机之上,虚拟机帮Java屏蔽底层的指令集,让Java能够跨平台运行)

  • 内存模型以及分区,需要详细到每个区放什么?

    • 方法区(method area): 方法信息
    • 本地方法栈(native method area): 本地方法
    • 堆(heap): 堆在内存中并不是一块连续的区域,物理上是分散的,但逻辑上是连续的,遇到一条new的指令时,为新生对象分配内存空间,有两种方式,指针碰撞,空间列表
      • 指针碰撞: 将内存逻辑上分为两边,一边是空闲的,一边是在用的,指针指向分界点,当需要分配内存的时候只要移动指针即可,只适用于内存规整的情况
      • 空间列表: 虚拟机必须维护一个列表,用于记录哪些内存是可用的,在需要进行分配的时候,就从列表中找出一块足够大的空间进行分配并更新列表
    • 栈(stack): 主要用来存放基本类型变量,局部变量以及对象的引用,方法的调用出入,栈的内存区域是连续的,有大小限制的,如果超出了就会抛出stackOverflowError异常,每个方法的调用都会对应着一个栈帧,有栈帧的入栈就有栈帧的出栈
  • 堆是存放对象以及数组的区域,分为年轻代和年老代
    • 年轻代又被分为一个Eden和两个Survivor区,即伊甸园和存活区
    • 假设有10个方格,则其中8个是Eden区,两个是Survivor区
    • 对象会在Eden区创建,当这两个区满了之后会将还存活的对象复制到另一个空白区Minor GC. 年轻代的对象有98%都是朝生夕死的
    • 如果年轻代不够放了,就放在年老代
    • 还有一种情况,对象在年轻代中存活的太久了
    • 每当进行一次复制回收的时候,还在年轻代中存活的对象就会加1岁,默认15岁就到年老代
    • 标记--清除--整理(标记好了就清除掉,最后整理成逻辑连续的区域)
    • 年老代存活的一般是大对象或很难死去的对象
    • 堆的设置
      • -Xms 10 m 堆的最小内存 10M
      • -Xmx 10 m 堆的最大内存 10M
      • -Xmn 10 m 设置新生代的内存大小
  • Java中GC标记(Garbage Collection)
    • 标记就是对一些已死的对象打上记号,有以下两种方法

      • 引用计数: 实现起来比较简单,就是给对象添加一个引用计数器,每当有一个地方引用它时就加1,引用失效时就减1,当计数器为0时就标记可回收,但很多主流的虚拟机并没有采用这种方法,因为它很难解决几个对象之间循环引用的问题
      • 可达性分析: 通过将一些称为“GC Roots”的对象作为起始点,从这些节点开始搜索和该节点发生直接或者间接引用关系的对象,将这些对象以链的形式组合起来,形成一张“关系网”,又叫做“引用链”,最后垃圾回收器就回收一些不在这张关系网上的对象
        • 栈帧中的引用对象(栈中的)
        • 静态属性引用的对象(方法区中的)
        • 常量引用的对象(方法区中的)
        • 本地方法栈中JNI引用的对象(本地方法栈中的)
  • Java中鲜为人知的二次标记
    • 所有的类都继承了Object类,因此,也默认实现了finalize方法。在该对象被回收之前,该对象的finalize方法会被调用。这里的被回收之前指的就是被标记之后,如果开发者重写了finalize方法,则该对象会被重新加入到引用链,即关系网中。面对同一个对象,他的finalize方法只会被调用一次
    • 二次标记
      • 第一次标记不在“关系网”中的对象
      • 第二次的话,就要先判断该对象有没有重写finalize方法
        • 如果没有,就直接回收
        • 如果重写了,则先放到一个队列中,并由虚拟机建立一个低优先级的线程来执行它,随后进行第二次小规模标记
  • 从GC日志分析堆内存
    • 由于GC线程和程序线程是并发执行的,当GC线程标记好了一个对象,此时程序中的线程又将该对象重新加入到了引用链中,虚拟机的解决办法是在一些特定位置设置一些“安全点”,当程序运行到这些“安全点”的时候就会暂停所有当前运行的线程(Stop The Word, STW), 暂停后重新找“GC Roots"进行关系的重建
    • 常见安全点的位置
      • 循环的末尾
      • 方法临返回前/调用方法的call指令后
      • 可能抛出异常的位置
    • 找到”GC Roots"也是花很长时间的,通过采用一个OopMap的数据结构来记录系统中存活的“GC Roots", 通过解释OopMap就可以找到堆中的对象,这种方式也叫准确式GC
    • GC和full GC是针对整个堆以及永久代的,时间长,尽量减少full GC的次数
  • Java中年轻代收集器(采用复制的收集算法)
    • Serial收集器: 一个单线程收集器,在进行回收的时候,必须暂停其它所有的工作进程,直到收集结束,用户体验不佳
    • ParNew收集器: 这个是Serial收集器的多线程版本,适用于多核CPU的设备
    • Parallel Scavenge收集器,默认的年轻代收集器,关注的是一个可控的吞吐量,吞吐量=运行代码的时间/(运行代码的时间+GC的时间),开启自适应调节策略
  • Java中年老代收集器,一般是大对象以及生命很顽强的对象(标记--清除--整理)
    • Serial Old收集器: 是Serial收集器的老年代版本,同样是单线程
    • Paraller Old收集器: 关注系统的吞吐量
    • CMS(Concurrent Mark Sweep)收集器: 是一种以最短停顿时间为目标的收集器
    • 标记
      • 初始标记----需要STW,直接关联
      • 并发标记----不需要STW,间接关联
      • 重新标记----需要STW,修改在上一步标记中有了变动的对象
      • 并发清除

初始Java虚拟机的更多相关文章

  1. 翻译Java虚拟机的结构

    英文原版:  https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html 直接谷歌翻译: Java SE规范 > Java虚拟机 ...

  2. 【深入Java虚拟机】之四:类加载机制

    类加载过程     类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载.验证.准备.解析.初始化.使用和卸载七个阶段.它们开始的顺序如下图所示: 其中类加载的过程包括了加载.验 ...

  3. JVM学习(1)——通过实例总结Java虚拟机的运行机制

    俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及到的知识点总结如下: JVM的历史 JVM的运行流程简介 JVM的组成(基于 Java 7) JVM调优参数:-Xmx和-Xms ...

  4. Elasticsearch Java 虚拟机配置详解

    Elasticsearch对Java虚拟机进行了预先的配置.通常情况下,因为这些配置的选择还是很谨慎的,所以你不需要太关心,并且你能立刻使用ElasticSearch. 但是,当你监视ElasticS ...

  5. 如何写出让java虚拟机发生内存溢出异常OutOfMemoryError的代码

    程序小白在写代码的过程中,经常会不经意间写出发生内存溢出异常的代码.很多时候这类异常如何产生的都傻傻弄不清楚,如果能故意写出让jvm发生内存溢出的代码,有时候看来也并非一件容易的事.最近通过学习< ...

  6. Java虚拟机浅探

    简介 对于java开发人员了来说,对java虚拟机肯定有着或多或少的了解.因为有了虚拟机的存在,才会使得java的内存管理变得那么方便,不再像C++那样使用new/delete来直接管理内存.知名的j ...

  7. Java虚拟机及运行时数据区

    1.Java虚拟机的定义 Java虚拟机(Java Virtual Machine),简称JVM.当我们说起Java虚拟机时,可能指的是如下三种不同的东西: 抽象的虚拟机规范 规范的具体实现 一个运行 ...

  8. 《深入理解Java虚拟机》垃圾收集器

    说起垃圾收集(Garbage Collection,GC),大部分人都把这项技术当做Java语言的伴生产物.事实上,GC的历史远比Java久远,1960年诞生于MIT的Lisp是第一门真正使用内存动态 ...

  9. Java虚拟机各内存区域的位置及功能的介绍

    Java虚拟机运行时数据区: 相关区域介绍: 程序计数器: 功能:当前线程所执行字节码的行号指示器.若是Java方法记录指令地址,若为Native方法,则不记录 隔离性:线程隔离 Error:无 Ja ...

随机推荐

  1. html布局 左右固定,中间只适应,三种方法实现

    html布局 左右固定,中间只适应,三种方法实现 使用自身浮动法定位 //html <h3>使用自身浮动法定位</h3> <div id="left_self& ...

  2. CSS3 3D立体柜子实现

    1. [图片] 20140811233657.jpg 2. [图片] 120140811233846.jpg ​3. [代码][CSS]代码 body {      background-color: ...

  3. 之前收集的一波MaterialDesign库

    material https://github.com/rey5137/material MaterialDesignLibrary md控件库,可兼容到2.2. https://github.com ...

  4. css3加载spinner

    使用代码制作一个加载旋转器spinner 实现的原理是: 1.两个圆圈,其中一个圆圈是使用pseudo元素(:before)产生 2.由pseudo元素生成的圆通过负数的z-index而作用在下面 3 ...

  5. Python基础-常用模块OS

    模块:一个python文件就是一个模块,模块分三种: 1,标准模块,也就是python自带的模块,例如import  time,random,string等等 2,第三方模块,这种模块需要自己安装才能 ...

  6. codeforces 650D D. Image Preview (暴力+二分+dp)

    题目链接: http://codeforces.com/contest/651/problem/D D. Image Preview time limit per test 1 second memo ...

  7. php中五种常见的设计模式

    设计模式 一书将设计模式引入软件社区,该书的作者是 Erich Gamma.Richard Helm.Ralph Johnson 和 John Vlissides Design(俗称 “四人帮”).所 ...

  8. Xposed模块开发学习记录

    Xposed模块相关API可以参考在线文档: https://api.xposed.info/reference/packages.html     入门教程可以参考: https://github. ...

  9. UILabel的富文本显示选项

    UILabel的富文本格式设置 1.实例化方法和使用方法 实例化方法: 使用字符串初始化 - (id)initWithString:(NSString *)str; 例: NSMutableAttri ...

  10. 浏览器全屏的JS代码实现

    方法一:该方法是从一个网上的效果看到不错,然后自己就拿来下来实验了一下,还是比较满意度,下面直接给出代码 <!DOCTYPE HTML> <html lang="en-US ...