<ignore_js_op>

Class Loader类加载器
负责加载class文件,class文件在文件开头有特定的文件标识,并且ClassLoader只负责class文件的加载,至于它是否可以运行,则由Execution Engine决定。

Method Area方法区(永久区)
方法区是被所用的线程共享,所有字段和方法字节码,以及一些特殊方法如构造函数,接口代码也是再此定义。简单说,所有定义的方法的信息都报错在该区域,此区间属于共享区间。
静态变量+常量+类信息+运行时常量池存在方法区中,它存储了每一个类的结构信息

注意:Java8去永久代,用元空间 替代。永久代使用的是JVM的堆内存,但是元空间并不在虚拟机中华而是使用本机的物理内存。

Heap堆 
栈管运行,堆管存储

堆是线程共享区域,是java虚拟机管理最大的一块区域。此区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。

PC Register 程序计数器
每一个线程都有一个程序计数器,就是一个指针,指向方法区中的方法字节码(下一个将要执行的指令代码),由执行引擎读取下一条指令,是一个非常小的内存空间,几乎可以忽略不记。线程私有。此区域是唯一一个没有OutOfMemoryError(OOM)的区域。

VM Stacks 虚拟机栈
栈管运行,堆管存储

线程私有。

虚拟机栈描述的是Java方法执行的内存模型:每一个方法在执行的同时都会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从调用直到执行完的过程,就对应一个栈帧在虚拟机栈中入栈到出栈的过程。

Native Method Stack 本地方法栈
    它的具体做法是  Natice Method  Stack 中登记native 方法,在Execution Engine 执行时加载native libraies。和虚拟机栈一样,都是线程私有的。

Native Interface
  本地接口的作用是融合不同的编程语言为Java所用,它的初衷是融合C/C++程序,Java诞生的时候是C/C++横行的时候,想要立足,必须有调用C/C++程序。目前,该方法使用的越来越少了,因为现在的异构领域间的通信很发达,比如可以使用Socket通信,也可以用WebService等等。
栈:一般指虚拟机栈
1)对于栈来说不存在垃圾回收问题。

2)基本类型的变量和对象的引用变量都在函数的栈内存中分配。

栈帧
栈帧(Stack Frame)是用于支持虚拟机运行方法调用和方法执行的数据结构,它是虚拟机运行时数据区中的虚拟机栈(Virtual Machine Stack)的栈元素。栈帧存储了方法的局部变量表、操作数栈、动态链接和方法返回地址等信息。每一个方法从调用开始至执行完成的过程,都对应着一个栈帧在虚拟机栈里面从入栈到出栈的过程。
<ignore_js_op> 
堆堆内存示意图
Eden:S0:S1=8:1:1

新生代:老年代=1:2 (新生代占堆的1/3,老年代占堆的2/3)

在新生代中存活15(默认)次以上才被放入老年代中
<ignore_js_op>

堆内存调优
参数        含义        demo
-Xms        设置初始分配大小,默认为物理内存的“1/64”        -Xms5m
-Xmx         最大分配内存,默认为物理内存的“1/4”        -Xms20m
-XX:+PrintGCDetails         输出详细的GC处理日志        -XX:+PrintGCDetails
-XX:+PrintCommandLineFlags         可以将隐式或者显式传给虚拟机的参数输出        XX:+PrintCommandLineFlags
-Xmn        设置新生代的绝对大小,新生代一般会设置整个堆空间的1/3到1/4左右        -Xmn20m
-XX:SurvivorRatio        用来设置新生代中eden空间和form/to空间的比例                                                                -XX:SurvivorRatio=eden/from=eden/to        -XX:SurvivorRatio=2
-XX:NewRatio        设置新生代和老年代的比例 -XX:NewRatio=老年代/新生代        -XX:NewRatio=2
-Xss        制定线程的最大栈空间,整个参数也直接决定了函数课调用的最大深度        -Xss5m
-XX:MaxTenuringThreshold        新生代经过多少次GC后进入老年代,默认为15        -XX:MaxTenuringThreshold=15
-XX:PretenureSizeThreshold        设置对象的大小超过在制定的大小之后,直接晋升老年代 ,后面的1000为100k        -XX:PretenureSizeThreshold=1000

在实际工作中,我们可以直接将初始的堆大小与最大堆大小设置相等,这样的好吃是可以减少程序运行时的垃圾回收次数,从而提高性能。

收集算法
口诀
频繁收集Yong区
较少收集Old区
基本不动Perm区
标记清除算法
老年代一般是由标记清除或者是标记清除与标记整理的混合实现
优点:不需要额外空间(和复试算法的缺点2比)
缺点:  1)有碎片,空闲空间不连续
            2)两次扫描,效率低
             3)需要一个内存空间记录哪是空,哪是非空

复制算法
年轻代中使用的Minor GC  ,这种GC算法采用的是复制算法(Copying)
优点:没有碎片
缺点:1)如果对象存活率很高(极端一点,100%),将全部数据复制费时费力
          2)浪费一了   survice 1 的空间
标记整理算法
老年代一般是由标记清除或者是标记清除与标记整理的混合实现
优点:无碎片,不需要额外空间
缺点:效率低,低于复制算法

垃圾收集器
<ignore_js_op>
Serial收集器
serial收集器依然是虚拟机运行在Client模式下的默认新生代收集器。
复制算法收集器。
ParNew收集器
ParNew收集器是Serial收集器的多线程版本。
复制算法收集器。
Parallel Scavenage收集器
关注点为吞吐量
吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间)
复制算法收集器
Serial Old收集器
标记-整理算法
Serial收集器的老年版
Parallel Old收集器
标记-整理算法
在注重吞吐量和CPU资源敏感的场合,都可以优先考虑Parallel Scavenge 加 Parallel Od
Parallel Old是Parallel Scavenge收集器的老年带版本
CMS收集器
标记-清除算法
CMS收集器数一种以获取最短回收停顿时间为目标的收集器。
收集器步骤:
1)初始标记
2)并发标记
3)重新标记
4)并发清除
优点:并发收集、低停顿
缺点:CMS收集器对CPU资源非常敏感
          无法处理浮动垃圾
          标记-清除法的缺点,有碎片
G1收集器
特点:并发与并行、分代收集、空间整理、可预测停顿
类加载机制
<ignore_js_op>

注意:
加载会调用静态代码块
初始化会调非静态代码块和构造方法
先加载类在初始化类,加载只加载一次
加载和初始化不一样
加载的是类的模板

初试化的是类的实例对象
1)静态的大于代码块,代码块大于构造方法
静态块先执行,并且只执行一次
代码块比构造方法先执行,并行new几次运行几次(运行结果)
public class Person {

public Person() {
        System.out.println("Person 构造方法");
    }

static {
        System.out.println("Person 静态代码块");
    }

{
        System.out.println("Person 普通代码块");
    }

}

public class Start {
    public static void main(String[] args) {
        Person person = new Person();
        System.out.println("-------");
        Person person2 = new Person();
    }
}
<ignore_js_op>

2)通过数组定义引用类,不会触发此类的加载
通过数组定义引用类,不会加载此类,因为加载此类必定会调用static静态代码快
public class Start {
    public static void main(String[] args) {
        Person[] persons = new Person[10];
    }
}
<ignore_js_op>

3)加载子类会同时加载和初始化父类
先执行父类的静态块(看下图运行结果)
在执行子类的静态块(看下图运行结果)
在执行父类的普通块和构造方法(看下图运行结果)
最后执行子类的普通块和构造方法(看下图运行结果)
public class Man extends Person {
    public Man() {
        System.out.println("Man 构造方法");
    }

static {
        System.out.println("Man 静态代码块");
    }

{
        System.out.println("Man 普通代码块");
    }
}
public class Start {
    public static void main(String[] args) {

Man man = new Man();
    }
}
<ignore_js_op>

4)通过子类引用父类的静态变量,不会导致子类加载和初始化,会导致父类加载,不会导致父类初始化
通过子类使用父类的静态变量,不会加载子类,会加载父类
会调用父类的静态代码块,不会调用父类的普通代码块
不会加载子类,自然不会调用子类的静态代码块
public class Person {

public Person() {
        System.out.println("Person 构造方法");
    }

static {
        System.out.println("Person 静态代码块");
    }

{
        System.out.println("Person 普通代码块");
    }

//静态成员变量
    public static int value = 1024;

}

class Man extends Person {
    static {
        System.out.println("Man 静态代码块");
    }
}

public class Start {
    public static void main(String[] args) {
        System.out.println(Man.value);
    }
}
<ignore_js_op>

5)常量(final)在编译阶段会存入调用类的常量池中,本质上没有直接引用到定义常量的类,因此不会触发定义常量的类的加载和初始化。
public class Person {

static {
        System.out.println("Person 静态代码块");
    }

{
        System.out.println("Person 普通代码块");
    }

//静态final成员变量
    public static final int value = 1024;

}

public class Start {
    public static void main(String[] args) {
        System.out.println(Person.value);
    }
}
<ignore_js_op>

更多技术资讯可关注:itheimaGZ获取

JVM笔记(一)的更多相关文章

  1. JVM笔记(虚拟机各内存的介绍)

    JVM笔记 java代码执行分为两部分:javac编译     java执行 代码并不是由上往下执行的,会经过编译期重排序进行优化,存在依赖关系的代码不会被重排序,保证了代码最终执行结果的正确性! j ...

  2. JVM笔记-Java技术体系与JVM概述

    1. 简述 Java 不仅仅是一门编程语言,还是一个由一系列计算机软件和规范组成的技术体系. Java 的广告词为 "一次编写,到处运行",之所以能够做到"跨平台&quo ...

  3. JVM笔记五-堆区

    JVM笔记五-堆区 在JVM中,堆区是重中之重.通过前面文章的学习,我们知道了,栈区是不会有垃圾回收的,所以,经常说的垃圾回收,其实就是回收的是堆区的数据.在这里,我们将会看到传说中的,新生代.老年代 ...

  4. JVM笔记6-垃圾回收概述

    JVM进行垃圾回收时要考虑哪的问题如下: 1.如何判定对象为垃圾对象? 1.引用计数法:在对象中添加一个引用计数器,当有地方引用这个对象的时候,引用计数器的值就+1,引用失效的时候,计数器的值就-1, ...

  5. JVM笔记(三) 垃圾收集器(2)收集算法

    垃圾收集器2:收集算法 主要通过阅读<深入了解Java虚拟机>(周志明 著)和网络资源汇集而成,为本人学习JVM的笔记.同时,本文理论基于JDK 1.7版本,暂不考虑 1.8和1.9 的新 ...

  6. JVM笔记(二) 垃圾收集器(1)

    垃圾收集器 主要通过阅读<深入了解Java虚拟机>(周志明 著)和网络资源汇集而成,为本人学习JVM的笔记.同时,本文理论基于JDK 1.7版本,暂不考虑 1.8和1.9 的新特性,但可能 ...

  7. JVM笔记6-垃圾回收器

    JVM进行垃圾回收时要考虑哪的问题如下: 1.如何判定对象为垃圾对象? 1.引用计数法:在对象中添加一个引用计数器,当有地方引用这个对象的时候,引用计数器的值就+1,引用失效的时候,计数器的值就-1, ...

  8. todo JVM笔记

    之前给自己定了很多计划,要学Dubbo,Netty,SSHM源码,Tomcat源码...这些基本浅尝辄止,很难继续研读,过不了多久就忘了. 觉得还是基础不够,所以决定把<JVM>.< ...

  9. JVM笔记【1】-- 运行时数据区

    目录 (一)java内存区域管理 1.1 程序计数器 1.2 虚拟机栈 1.3 本地方法栈 1.4 java堆 1.5 方法区 1.5.1 运行时常量池 (二)直接内存 (一)java内存区域管理 C ...

  10. JVM笔记 -- JVM的发展以及基于栈的指令集架构

    2011年,JDK7发布,1.7u4中,开始启用新的垃圾回收器G1(但是不是默认). 2017年,发布JDK9,G1成为默认GC,代替CMS.(一般公司使用jdk8的时候,会通过参数,指定GC为G1) ...

随机推荐

  1. 在WSL Ubuntu1804中安装Docker

    一.系统环境 1.1 环境准备: Windows10 企业版 1909 Docker for Windows WSL Ubuntu1804 1.2 下载安装 Docker for Windows 1. ...

  2. Linux系统相关命令

    时间和日期 date cal 磁盘和目录空间 df du 进程信息 ps top kill 01. 时间和日期 序号 命令 作用 01 date 查看系统时间 02 cal calendar 查看日历 ...

  3. Django知识点集合

  4. Java之线程通信的方法

    /** * 线程通信的例子:使用两个线程打印 1-100.线程1, 线程2 交替打印 * * 涉及到的三个方法: * wait():一旦执行此方法,当前线程就进入阻塞状态,并释放同步监视器. * no ...

  5. git 推送到github最常用命令

    初始化仓库,上传到github中. git init git add README.md git commit -m "first commit" git remote add o ...

  6. SQL case when else 语句:选出年份等于1970的,选出的结果用科目和获奖者排序,同时把经济和化学2科放到最后:SELECT * FROM nobel_win WHERE year=1970 ORDER BY CASE WHEN subject IN ('Economics','Chemistry') THEN 1 ELSE 0 END ASC, subject, winner;

    SELECT * FROM nobel_win WHERE year=1970 ORDER BY  CASE WHEN subject IN ('Economics','Chemistry') THE ...

  7. Python笔记_第二篇_面向过程_第二部分_1.函数

    函数:这个词属于一个数学概念,在编程语言借鉴了这个概念,表现形式是一段程序代码的组合,也叫“程序集”.有过编程基础的人很容易理解这个概念,当我们编写程序越来越多的时候,程序设计大师们会把散乱的程序进行 ...

  8. Matlab高级教程_第一篇:Matlab基础知识提炼_06

    第十一节:图形操作 第十二节:文件的IO操作个格式化输出

  9. PHP 限制访问ip白名单

    一  上代码 config.php //ip白名单配置 'ipWlist'=>[ 'ifFilter'=>true, //是否开启白名单功能 'wlist'=>[ '10.0.0.1 ...

  10. 吴裕雄--天生自然python TensorFlow图片数据处理:No module named 'tensorflow.examples.tutorials'解决办法

    import numpy as np import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_dat ...