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) 垃圾收集器(目前就不往下深入学习了,这里留个问题,以后再学习)
jvm详解、GC、堆内存参数调优相关推荐
- JVM之堆Heap参数调优入门
JVM之堆Heap参数调优入门 目录: JVM体系结构概览 JVM之堆Heap参数调优入门 2.1 java7和 java8堆结构图 2.2 堆内存调优简介 1. JVM体系结构概览 2. JVM之堆 ...
- 实例详解 DB2 排序监控和调优
实例详解 DB2 排序监控和调优 http://automationqa.com/forum.php?mod=viewthread&tid=2882&fromuid=2
- JVM 参数配置及详解 -Xms -Xmx -Xmn -Xss 调优总结
堆大小设置 JVM 中最大堆大小有三方面限制:相关操作系统的数据模型(32-bt还是64-bit)限制;系统的可用虚拟内存限制;系统的可用物理内存限制.32位系统 下,一般限制在1.5G~2G;64为 ...
- JVM 参数配置及详解 -Xms -Xmx -Xmn -Xss 调优总结(点赞收藏)
堆大小设置 JVM 中最大堆大小有三方面限制: ①.相关操作系统的数据模型(32-bt还是64-bit)限制; ②.系统的可用虚拟内存限制; ③.系统的可用物理内存限制. 32位系统 下,一般限制在1 ...
- JVM详解(类加载,内存分配,GC,内存模型)
一. 背景 1. 前言 作为一位Java开发工作者,在关心业务代码开发的同时,我们也需要了解java底层时如何运作的,了解为什么说java是跨平台的语言,所以这一篇对JVM(java虚拟机)进行剖析和 ...
- java内存优化详解_jvm堆内存优化详解
在日常的运维工作中用到tomcat,都需要对tomcat中的jvm虚拟机进行优化,只有知道需要优化参数的具体用处,才能深刻体会优化jvm的意义所在. 在平常的工作中我们谈对jvm的优化,主要是针对ja ...
- Oracle 内存参数调优设置
Oracle 数据库系统中起到调节作用的参数叫初始化参数,数据库管理员根据实际情况需要适当调整这些 初始化参数以优化Oracle系统. 1 主要系统参数调优介绍 2 系统内存参数的分配 2.1 Ora ...
- oracle内存参数越大越好吗,什么是Oracle内存参数调优技术?
在实际的工作中灵活应用 , 使 oracle 的内存性能达到最优配置,提升应用程序反应速度,并进行合理的内存使用 . 实例结构 oracle 实例 = 内存结构 + 进程结构 oracle 实例启动的 ...
- PostgreSQL 内存参数调优
本文讨论PostgreSQL中一些管理内存参数,并对每个参数提供参考值建议. 1. 概述 GUC: Grand Unified Configuration 是postgreSQL对数据库参数进行管理的 ...
最新文章
- 代码: html 页面小效果 (集合,待补充)
- python之装饰器篇
- 根据URL参数显示网站地图
- oracle-Oracle试题
- Java this 关键字的用法
- Windows Phone 8.1 新特性 - 控件之应用程序栏
- 【C语言笔记初级篇】第四章:数组入门
- sprinboot整合activity
- php7.2连接mysql8_兼容 php 7.2 及 mysql 8
- 【TO DO!】二分查找各种情况大总结
- Django框架基础之session
- 【短时能量】基于matlab语音信号短时能量【含Matlab源码 1719期】
- 测试从业人员的职业规划
- arcmap怎么保存相对路径_如何将arcgis的mxd文档存储为相对路径
- PG系列3-客户端工具使用
- vanishing point detection in autopilot
- 360浏览器兼容模式下js失效的问题
- 三废的日常——什么是负载均衡
- 如何修改Microsoft edge浏览器主页?
- C++ make_shared() shared_ptr()用法(七)
热门文章
- 公司间交易学习笔记---概述
- NetTiers模板中各个选项的一些解释
- 【Breadth-first Search 】515. Find Largest Value in Each Tree Row
- 【数据结构与算法】排序 冒泡、插入、选择 O(n^2)
- java jdbc开启事务_spring jdbc 事务配置
- 华为手机丢失定位网站_手机端网站优化要从网站的设计和定位开始入手
- matlab cuda的.cu文件应该放在那里_无人机基于Matlab/Simulink的模型开发(连载一)
- html注册跳转php错误500,页面跳转后提示HTTP 异常 500(Internal Server Error):服务器尝试执行请求时遇到了意外情况...
- 蓝桥杯c语言a组2015,2015第七届蓝桥杯决赛C语言A组--穿越雷区(DFS)
- asterisk账号和拨号方案mysql存储(静态)