一些常见面试题:

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、堆内存参数调优相关推荐

  1. JVM之堆Heap参数调优入门

    JVM之堆Heap参数调优入门 目录: JVM体系结构概览 JVM之堆Heap参数调优入门 2.1 java7和 java8堆结构图 2.2 堆内存调优简介 1. JVM体系结构概览 2. JVM之堆 ...

  2. 实例详解 DB2 排序监控和调优

    实例详解 DB2 排序监控和调优 http://automationqa.com/forum.php?mod=viewthread&tid=2882&fromuid=2

  3. JVM 参数配置及详解 -Xms -Xmx -Xmn -Xss 调优总结

    堆大小设置 JVM 中最大堆大小有三方面限制:相关操作系统的数据模型(32-bt还是64-bit)限制;系统的可用虚拟内存限制;系统的可用物理内存限制.32位系统 下,一般限制在1.5G~2G;64为 ...

  4. JVM 参数配置及详解 -Xms -Xmx -Xmn -Xss 调优总结(点赞收藏)

    堆大小设置 JVM 中最大堆大小有三方面限制: ①.相关操作系统的数据模型(32-bt还是64-bit)限制; ②.系统的可用虚拟内存限制; ③.系统的可用物理内存限制. 32位系统 下,一般限制在1 ...

  5. JVM详解(类加载,内存分配,GC,内存模型)

    一. 背景 1. 前言 作为一位Java开发工作者,在关心业务代码开发的同时,我们也需要了解java底层时如何运作的,了解为什么说java是跨平台的语言,所以这一篇对JVM(java虚拟机)进行剖析和 ...

  6. java内存优化详解_jvm堆内存优化详解

    在日常的运维工作中用到tomcat,都需要对tomcat中的jvm虚拟机进行优化,只有知道需要优化参数的具体用处,才能深刻体会优化jvm的意义所在. 在平常的工作中我们谈对jvm的优化,主要是针对ja ...

  7. Oracle 内存参数调优设置

    Oracle 数据库系统中起到调节作用的参数叫初始化参数,数据库管理员根据实际情况需要适当调整这些 初始化参数以优化Oracle系统. 1 主要系统参数调优介绍 2 系统内存参数的分配 2.1 Ora ...

  8. oracle内存参数越大越好吗,什么是Oracle内存参数调优技术?

    在实际的工作中灵活应用 , 使 oracle 的内存性能达到最优配置,提升应用程序反应速度,并进行合理的内存使用 . 实例结构 oracle 实例 = 内存结构 + 进程结构 oracle 实例启动的 ...

  9. PostgreSQL 内存参数调优

    本文讨论PostgreSQL中一些管理内存参数,并对每个参数提供参考值建议. 1. 概述 GUC: Grand Unified Configuration 是postgreSQL对数据库参数进行管理的 ...

最新文章

  1. 代码: html 页面小效果 (集合,待补充)
  2. python之装饰器篇
  3. 根据URL参数显示网站地图
  4. oracle-Oracle试题
  5. Java this 关键字的用法
  6. Windows Phone 8.1 新特性 - 控件之应用程序栏
  7. 【C语言笔记初级篇】第四章:数组入门
  8. sprinboot整合activity
  9. php7.2连接mysql8_兼容 php 7.2 及 mysql 8
  10. 【TO DO!】二分查找各种情况大总结
  11. Django框架基础之session
  12. 【短时能量】基于matlab语音信号短时能量【含Matlab源码 1719期】
  13. 测试从业人员的职业规划
  14. arcmap怎么保存相对路径_如何将arcgis的mxd文档存储为相对路径
  15. PG系列3-客户端工具使用
  16. vanishing point detection in autopilot
  17. 360浏览器兼容模式下js失效的问题
  18. 三废的日常——什么是负载均衡
  19. 如何修改Microsoft edge浏览器主页?
  20. C++ make_shared() shared_ptr()用法(七)

热门文章

  1. 公司间交易学习笔记---概述
  2. NetTiers模板中各个选项的一些解释
  3. 【Breadth-first Search 】515. Find Largest Value in Each Tree Row
  4. 【数据结构与算法】排序 冒泡、插入、选择 O(n^2)
  5. java jdbc开启事务_spring jdbc 事务配置
  6. 华为手机丢失定位网站_手机端网站优化要从网站的设计和定位开始入手
  7. matlab cuda的.cu文件应该放在那里_无人机基于Matlab/Simulink的模型开发(连载一)
  8. html注册跳转php错误500,页面跳转后提示HTTP 异常 500(Internal Server Error):服务器尝试执行请求时遇到了意外情况...
  9. 蓝桥杯c语言a组2015,2015第七届蓝桥杯决赛C语言A组--穿越雷区(DFS)
  10. asterisk账号和拨号方案mysql存储(静态)