<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. ae基础二

    纯色文本操作快捷键:选中图层点击快捷键(变换)锚点:a(调节中心点)位置:p(左右移动)(利用位置k帧做动画)缩放:s(水平翻转垂直翻转)旋转:r(围绕中心点(锚点)进行旋转)不透明度:tu选中索引 ...

  2. macbook 一些php相关操作

    开启php: https://jingyan.baidu.com/article/67508eb434539f9cca1ce4da.html 配置多虚拟主机:  https://jingyan.bai ...

  3. Oracle之纵向数据转换横向数据

    资源二  来源  http://www.cnblogs.com/gkl0818/archive/2009/02/25/1398078.html 1.固定列数的行列转换如student subject ...

  4. Django_JavaScript

    JavaScript是什么 JavaScript是一种运行在客户端(浏览器)的编程语言,用来给网页添加动态功能. JavaScript的作用 最初目的 为了处理表单的验证操作 现在广泛的应用场景 网页 ...

  5. 基于JSP开发医院预约挂号系统 Java源码

    开发环境: Windows操作系统 开发工具: Eclipse+Jdk+Tomcat+MYSQL数据库 运行效果图: 源码及原文链接:http://javadao.xyz/forum.php?mod= ...

  6. goweb-表单

    表单 简单的处理一个登陆界面 package main import ( "fmt" "html/template" "log" " ...

  7. Linux inode 理解

    inode 硬盘的最小存储单位叫做"扇区"(Sector).每个扇区储存512字节(相当于0.5KB).操作系统读取硬盘的时候,不会一个个扇区地读取,这样效率太低,而是一次性读取一 ...

  8. base64字符串转化成图片

    package com.dhht.wechat.util; import sun.misc.BASE64Decoder;import sun.misc.BASE64Encoder; import ja ...

  9. Spring 如何解决循环依赖的问题

    Spring 如何解决循环依赖的问题 https://blog.csdn.net/qq_36381855/article/details/79752689 Spring IOC 容器源码分析 - 循环 ...

  10. Win10用Windows照片查看程序(照片查看器)打开图片

    以上方法只能一个个添加,也有人说不好使,这里给出一个我写的批处理程序,反正我一直用着很好.   ::复制以下内容到记事本: @echo off&cd\&color 0a&cls ...