jvm详解、GC、堆内存参数调优

一些常见面试题:

在这里插入图片描述

JVM的位置(运行在操作系统上,与硬件没有直接的交互)

在这里插入图片描述

一、jvm体系结构(记住背下来)

运行时数据区:有亮色的有灰色的,灰色的就是占得内存非常小,几乎不存在GC垃圾回收,并且线程独占的,亮色的存在垃圾回收,并且所有线程共享。

在这里插入图片描述

二、类装载器

(看做成快递员,把class文件(class文件开头有特定的文件标示cafe babe)字节码加载到内存,并将这些内容转换成方法区中的运行时数据结构并且ClassLoader只负责class文件的加载,至于是否可以运行,由Execution Engine决定)
在这里插入图片描述
在这里插入图片描述

类装载器有哪几个?

1-启动类加载器,负责加载%JAVA_HOME%\bin目录下的所有jar包,或者是-Xbootclasspath参数指定的路径;
2-扩展类加载器:负责加载%JAVA_HOME%\bin\ext目录下的所有jar包,或者是java.ext.dirs参数指定的路径;
3-应用程序类加载器:负责加载用户类路径上所指定的类库,如果应用程序中没有自定义加载器,那么次加载器就为默认加载器。

加载器之间的层次关系:

在这里插入图片描述

public class MyObject {public static void main(String []args){Object object = new Object();MyObject myObject = new MyObject();System.out.println(object.getClass().getClassLoader());System.out.println(myObject.getClass().getClassLoader());}
}
运行结果:启动类加载器来加载java自带的类,BootStrap是C++写的所以输出的null;

在这里插入图片描述

package JVM;public class MyObject {public static void main(String []args){Object object = new Object();System.out.println(object.getClass().getClassLoader());System.out.println();System.out.println();System.out.println();MyObject myObject = new MyObject();System.out.println(myObject.getClass().getClassLoader());System.out.println(myObject.getClass().getClassLoader().getParent());System.out.println(myObject.getClass().getClassLoader().getParent().getParent());}
}

在这里插入图片描述

双亲委派机制:

双亲委派机制得工作过程:
1-类加载器收到类加载的请求;
2-把这个请求委托给父加载器去完成,一直向上委托,直到启动类加载器(bootstrap);
3-启动器加载器检查能不能加载(使用findClass()方法),能就加载(结束);否则,抛出异常,通知子加载器进行加载。
4-重复3;

当加载一个类会先到启动类加载器去找,找得到就用,找不到就到扩展类加载器找,找不到再去应用程序类加载器去找。(从顶层往下开始找)
在这里插入图片描述

双亲委派机制的理由?

是沙箱安全机制

例:

String类,String是java.lang包下的类,默认情况下是启动类加载器进行加载的。假设我也自定义一个String。现在你会发现自定义的String可以正常编译,但是永远无法被加载运行。
这是因为申请自定义String加载时,总是启动类加载器,不会是其他的加载器,也就是不会用应用程序加载器加载。

package java.lang;public class String {public static void main(String[] args) {System.out.println(1111);}
}

运行结果:是无法被加载的在这里插入图片描述

三、本地方法栈(加载native方法,了解)

在这里插入图片描述

四、程序计数器(类似一个指针,一条指令执行完用来指向下一个指令 )

在这里插入图片描述
在这里插入图片描述

五、方法区(类的模板工厂)

六、java栈(灰色,线程私有,不存在gc )

栈中主要存储3类数据:
本地变量:输入参数和输出参数,方法内的变量
栈操作:记录出栈、入栈的操作
栈帧数据:包括类文件、方法等。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

七、堆(一个jvm实例只存在一个堆空间,大小可以调节)

堆分为三部分:新生区,养老区,永久区
新生区分为:伊甸区、幸存者0区、幸存者1区
java8把永久区改为元空间
(物理上堆分为新生区、养老区;逻辑上分为新生区、养老区、元空间)
在这里插入图片描述

java7之前, java8把永久区换成了元空间()

在这里插入图片描述
在这里插入图片描述

详细版:复制 -> 清空 -> 交换

在这里插入图片描述

对象生命周期和GC

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

jvm堆参数调优:

-Xms:start起始内存
-Xmx:max最大内存

-Xmn:一般不会调这个参数!
在这里插入图片描述
在这里插入图片描述

java8中,永久代被移除,被元空间取代,元空间的本质和永久代类似。
元空间与永久代之间最大的区别在于:
永久带使用的JVM的堆内存,但是java8以后的元空间并不在虚拟机中而是使用本机物理内存

因此,默认情况下,元空间的大小仅受本地内存限制。类的元数据放入native memory,字符串池和类的静态变量放入java堆中,这样可以加载多少的类的元数据就不再有MaxPermSize控制,而由系统的实际可用空间来控制。

在这里插入图片描述
默认
-Xms:为物理内存大小的1/64
-Xmx:为物理内存大小的1/4
在这里插入图片描述

jvm参数调优:实际-Xms和-Xmx大小必须一致,防止GC和应用程序争抢内存,理论值的峰值和峰度忽高忽低。

先查看内存大小:
在这里插入图片描述

package JVM;public class heap {public static void main(String[] args) {long maxMemory = Runtime.getRuntime().maxMemory();//返回java虚拟机试图使用的最大内存容量long totalMemory = Runtime.getRuntime().totalMemory();//返回java虚拟机的总内存容量System.out.println("-Xmx:MAX_MEMORY = " + maxMemory + "(字节)、" + (maxMemory / (double)1024 / 1024) + "MB");System.out.println("-Xms:TOTAL_MEMORY = " + totalMemory + "(字节)、" + (totalMemory / (double)1024 / 1024) + "MB");}
}

更改-Xms和-Xmx参数:-Xms1024m -Xmx1024m -XX:+PrintGCDetails

在这里插入图片描述
运行:
在这里插入图片描述
上图: 新生代+老年代的内存大小等于981.5MB,元空间用的是物理内存空间!

GC 垃圾收集机制(分代回收算法)

分代收集算法:

  • 次数上频繁收集Young区
  • 次数上较少收集Old区
  • 基本不动元空间
    在这里插入图片描述
    在这里插入图片描述

GC 4个算法

在这里插入图片描述

1.引用计数法(了解,不用)

在这里插入图片描述

2. 复制算法(年轻代中的GC,不会产生内存碎片速度快,但是消耗内存空间)

当Eden区满了,会回收,没有被回收的会和survivorFrom区没有被回收的使用复制算法复制到survivorTo区,然后from区和Eden区全部清空,然后from区和to去进行交换(from区变成to区,to区变成from区,所以说谁空谁是to),对象没熬过一次Minor GC年龄就会+1,当对象年龄达到默认设置的15
(-XX:MaxTenuring Threshold参数来设置)那么就会被送到老年代。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述在这里插入图片描述

3.标记清除(老年代使用,一般由标记清除或者是标记清除与标记整理的混合实现。。。与复制算法比较:节约了内存空间,但是会产生内存碎片,标记和清除会扫描两次耗时严重)

在这里插入图片描述
在这里插入图片描述
当程序运行期间,若可以使用的内存被耗尽的时候,GC线程就会被触发并将程序暂停,随后将要回收的对象标记一遍,最终统一回收这些对象,完成标记清理工作接下来便让应用程序恢复运行
在这里插入图片描述

4.标记压缩(标记完成后不会进行清除,而是所有存活对象都像一端移动,然后直接清除边界以外的内存,这样不会产生内存碎片,但是时间会更长)

原理:
在这里插入图片描述
工作中实际使用:(标记压缩,多次GC后才会进行清除)
在这里插入图片描述

GC算法小总结:

在这里插入图片描述

有没有最好的GC算法??(没有最好的算法,只有最适合的算法,所以采用分代收集,标记整理好但是耗时)

但是有个G1垃圾收集算法: Garbage First(G1) 垃圾收集器(目前就不往下深入学习了,这里留个问题,以后再学习)
在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/437556.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【转】!Dynamics 365 Online通过OAuth 2 Client Credential授权(Server-to-Server Authentication)后调用Web API

微软动态CRM专家罗勇 ,回复332或者20190505可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me! 本文很多内容来自 John Towgood 撰写的Dynamics 365 Online Authenticate with Client Credentials &#xff0c…

JMM(java内存模型)

这篇文章写得挺好的:https://blog.csdn.net/javazejian/article/details/72772461 在多线程环境下,线程之间的要通信,就不得不提JMM(java内存模型) 在JVM内部使用的java内存模型(JMM)将线程堆栈和堆之间的内存分开 jmm的承诺: 1.原子性 2.可…

【转】Postman 生成接口文档

引言 几个朋友想做一个前后端分离的项目,接口文档的重要性那是不言而喻的。生成接口文档的方法真的太多了,Yapi、Swagger等等。但是想公网上访问接口文档并修改的话,还得购买服务器,部署上去。穷码农,哪有钱购买服务器…

JVM的进阶学习(GC Roots、JVM调优与参数配置、)

1. GC Roots,可达性分析 从GC roots的对象作为起始点,从GC Roots对象开始向下搜索,如果一个对象到GCRoots没有任何引用链相连,则说明对象不可用。即给定一个集合的引用作为根出发,通过引用关系遍历对象图,能…

【转】图解phpstorm常用快捷键

转载自 https://segmentfault.com/a/1190000004225643 查询快捷键 CTRLN 查找类 CTRLSHIFTN 全局搜索文件 ,优先文件名匹配的文件 CTRLSHIFTALTN 查找php类名/变量名 ,js方法名/变量名, css 选择器 CIRLB 找变量的来源,跳到变量申明处 (CTRL 鼠标单击 也可以) CTRL…

HQL写topN、Spark写topN

HQL写topN用窗口函数rank() 、row_number()、dense_rank() 1、rank(),跳跃排序,假如第一第二相同,那么第三个就是3 select * from( select id, cn, score, rank() over(partition by id order by score desc)as ranks from top N ) A where ranks&…

【转】Dynamics 365 CRM 开发架构简介

目录 概览 名词解释连接到Dynamics 365 CRM Web APIOrganization service选择 - Web API vs. Organization service扩展服务端扩展应用端正文 Dynamics 365 CRM提供了多种编程模型,你可以灵活地按需选用最佳模式。 本文是对Dynamics 365 CRM编程模型的综述。 回…

查找算法-(顺序查找、二分查找、插值查找、斐波那契查找)

1)顺序查找或叫线性查找 就是顺序遍历匹配 2)二分查找 package search;public class BinarySearch {/*** 二分查找数组必须有序*//**** param arr 数组* param left 左边索引* param right 右边索引* param findVal 要查找的值* return 找到就返回&…

数据结构 - 哈希表(用数组+链表实现存储员工信息,添加增删查功能)

package hashtab;import java.util.Scanner;public class HashTabDemo {public static void main(String[] args) {//创建一个hashTabHashTab hashTab new HashTab(7);//写一个简单菜单来测试String key "";Scanner sc new Scanner(System.in);while (true){Syste…

数据结构 - 树(二叉树的 前序、中序、后序 遍历)

二叉树遍历(前序中序后序,主要是看父节点的输出顺序) package tree;public class BinaryTreeDemo {public static void main(String[] args) {//先需要创建一颗二叉树BinaryTree binaryTree new BinaryTree();//创建需要的节点HeroNode root…

【转】c# 操作webservice(经典入门教程+MSDN必胜)(有自己修改的部分)

Web Service基本概念 Web Service也叫XML Web Service WebService是一种可以接收从Internet或者Intranet上的其它系统中传递过来的请求,轻量级的独立的通讯技术。是:通过SOAP在Web上提供的软件(服务),使用WSDL文件进行&#xff0…

数据结构 - 二叉树(前序中序后序查找)

public static int i 1, j 1, k 1;//编写前序查找方法public HeroNode preOrderSearch(int no){System.out.println("前序遍历"(i)"次");if (this.no no){return this;}HeroNode heroNode null;if (this.left ! null){heroNode this.left.preOrderSea…

数据结构 - 二叉树(删除节点)

因为二叉树是单向的,所以要判断当前节点的子节点(左或右)是否是被删除的节点 //递归删除节点//规定:如果是叶子节点就删除节点,如果非叶子节点就删除子树public void delNode(int no){if (this.left !null && this.left.no no){this…

【转】OData – the best way to REST–实例讲解ASP.NET WebAPI OData (V4) Service Client

一、概念介绍 1.1,什么是OData? 还是看OData官网的简单说明: An open protocol to allow the creation and consumption of queryable and interoperable RESTful APIs in a simple and standard way. 这是一个开放的数据查询和服务协议&…

数据结构 - 顺序存储二叉树(前序中序后序遍历)

就是逻辑上是二叉树,物理上是一个数组 需求 package tree;public class ArrayBinaryTreeDemo {public static void main(String[] args) {int arr [] {1, 2, 3, 4, 5, 6, 7};ArrayBinaryTree arrayBinaryTree new ArrayBinaryTree(arr);//arrayBinaryTree.preOrde…

【转】WCF Data Service 使用小结 (一)—— 了解OData协议

最近做了一个小项目,其中用到了 WCF Data Service,之前是叫 ADO.NET Data Service 的。关于WCF Data Service,博客园里的介绍并不多,但它确实是个很好的框架。可以很方便地通HTTP来访问数据库,如果你是做富客户端开发的…

数据结构 - 线索化二叉树(线索化与遍历)

!!(这里我debug很久才理解过来)** 这里8的前驱为null,所以8的leftType1,但是6是没有后继的或者说后继为null但是rightType为0(因为后继是在下一个节点来进行连接的,6没有下一个节点,所以不能实现后继的线索化,所以righ…

【转】WCF Data Service 使用小结(二) —— 使用WCF Data Service 创建OData服务

在 上一章 中,介绍了如何通过 OData 协议来访问 OData 服务提供的资源。下面来介绍如何创建一个 OData 服务。在这篇文章中,主要说明在.NET的环境下,如何使用 WCF Data Service 来创建OData服务。当然,对于 JAVA 或者其它平台&…

算法 - 堆排序(大顶堆、小顶堆)

用的是顺序存储二叉树,也就是数组实现的二叉树,遍历的时候按照的是二叉树的形式 代码实现 package tree;import java.util.Arrays;public class HeapSort {public static void main(String []args){int [] arr {4, 6, 8, 5, 9,-1,-1,2,4,5,6,88};heapS…

【转】WCF Odata 开放数据协议应用

OData简介 说起 WCF Data Service ,不得不说的是 OData。对于一个标准的 Web 服务,它往往会提供了一些功能,比如说:订货、退货这些,然后使用者通过HTTP协议来使用这些功能。这是面向服务的基本思想,然而面…