JVM面试题

2023-11-02

JVM相关

jvm详解、GC、堆内存参数调优_春_的博客-CSDN博客_jvm堆内存调优

常见JVM面试题及答案整理_Java程序员-张凯的博客-CSDN博客_jvm面试题

JVM的模块

 

 

 

 

常见问题

JVM的理解?java8虚拟机和之前的变化更新?

撤销了永久带,引入了元空间

OOM?栈溢出?怎么分析?

常见的OOM情况有三种:

1)**java.lang.OutOfMemoryError: Java heap space** ------>java堆内存溢出,此种情况最常见,一般由于内存泄露或者堆的大小设置不当引起。对于内存泄露,需要通过内存监控软件查找程序中的泄露代码,而堆大小可以通过虚拟机参数-Xms,-Xmx等修改。

2**)java.lang.OutOfMemoryError: PermGen space/ Metaspace------>java永久代(元数据)溢出,即方法区溢出了,一般出现于大量Class或者jsp页面,或者采用cglib等反射机制的情况,因为上述情况会产生大量的Class信息存储于方法区。此种情况可以通过更改方法区的大小来解决,使用类似-XX:PermSize/MetaspaceSize=64m -XX:MaxPermSize/MaxMetaspaceSize =256m的形式修改。另外,过多的常量也会导致方法区溢出。

3)**java.lang.StackOverflowError -**----->不会抛OOM error,但也是比较常见的Java内存溢出。JAVA虚拟机栈溢出,一般是由于程序中存在死循环或者深度递归调用造成的,栈大小设置太小也会出现此种溢出。可以通过虚拟机参数-Xss来设置栈的大小。

JVM性能调优

 

  • 调整JVM参数

  • 分析dump文件

  • 分析内存泄露

  • 监控GC状态

JVM常用调优参数有哪些?

 

内存快照如何抓取?怎么分析dump文件?

下载MemoryAnalyzer

导入dump文件

分析图表、对象树

dump可以是内存溢出时让其自动生成,或者手工直接导。配置jvm参数-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/biapp/m.hprof

手工直接导,PID为进程号

jmap -dump:live,format=b,file=m.hprof PID

jvm的位置

jvm的体系结构

 

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

类加载器

1)通过一个类的全限定名类获取定义此类的二进制字节流。2)将字节流的所代表的静态存储结构转化成方法区运行时的数据结构。3)在内存中生成一个代表这个类的java.lang.Class的对象,做作为方法区的这个类各种数据访问的入口。 验证就是为了确保Class文件字节流中包含的信息符合当前虚拟机的要求,并且不会危害到虚拟机本身。 准备阶段是给类变量赋予初始值的阶段。这里的初始值是指变量默认的值,并不是用户赋予的初始值。 初始化阶段是类加载的最后一步。是给类变量赋予初始值

类加载器就是把类加载阶段中的”通过一个类的全限定名来获取描述此类的二进制字节流”这个动作放到java虚拟机外部来实现的代码模块。

双亲委派模型

如果一个类加载器收到了类加载请求,它并不会自己先去加载,而是把这个请求委托给父类的加载器器制定; 如果父类加载器还存在其父类加载器,则进一步向上委托,依次递归,请求最终到达顶层的启动类加载器; 如果父类加载器可以完成类加载任务,就成功返回,倘若父类加载器无法完成此加载任务,子加载器才会尝试自己去加载,这就是双亲委派模式

启动类加载器、扩展类加载器、应用类加载器(系统类加载器)、用户自定义类加载器。 启动类加载器:这个类负责将存放在JAVA_HOME/lib目录或者被-Xbootclasspath参数所指定的路径中的并且是虚拟机内存中。 扩展类加载器:负责加载JAVA_HOME/lib/ext目录中或者被java.ext.dirs系统变量指定路径中的所有类库,开发者可以直接使用扩展类加载器。 应用程序类加载器:负责加载用户类路径上指定的类加载器,一般情况下就是程序中默认的类加载器。 各个类加载器之间的关系:

 

    public static void main(String[] args) {
        ClassLoader cl = new Student().getClass().getClassLoader();  //应用程序类加载器
        ClassLoader parent = cl.getParent();   //扩展类加载器
        ClassLoader grand = parent.getParent();  //启动类加载器,C++编写的,因此没有toString打印
        System.out.println(cl);
        System.out.println(parent);
        System.out.println(grand);
        System.out.println("String类的类加载器是:" + new String("ddf").getClass().getClassLoader());
    }
sun.misc.Launcher$AppClassLoader@18b4aac2
sun.misc.Launcher$ExtClassLoader@6d6f6e28
null
String类的类加载器是:null

启动类加载器 这个类加载器是jvm自己实现的,加载home/lib 或者-Xbootclasspath 指定的路径下的而且文件名能被识别(rt.jar,tools.jar 名字不符合也不会加载)
扩展类加载器 以代码的形式实现的 ,他负责加载home/lib/ext目录中或者被java.ext.dirs系统变量所指定的类库
应用程序类加载器 他负责加载ClassPath上所有的类库
自定义类加载器 可以选择继承java.lang.ClassLoader类的方式实现自己的类加载器来满足一些特殊的需求 JDK1.2之前 会去继承ClassLoader类,并且重写loadClass方法,1.2之后不建议覆盖loadClass方法,而是建议把逻辑写在findClass()方法里面或者可以直接继承URLClassLoader类

沙箱安全机制

 Java安全模型的核心就是Java沙箱(sandbox),什么是沙箱?沙箱是一个限制程序运行的环境。沙箱机制就是将 Java 代码限定在虚拟机(JVM)特定的运行范围中,并且严格限制代码对本地系统资源访问,通过这样的措施来保证对代码的有效隔离,防止对本地系统造成破坏。沙箱主要限制系统资源访问,那系统资源包括什么?——CPU、内存、文件系统、网络。不同级别的沙箱对这些资源访问的限制也可以不一样。

  所有的Java程序运行都可以指定沙箱,可以定制安全策略。

Native

1、一个native方法就是一个Java调用非Java代码的接口。一个native方法是指该方法的实现由非Java语言实现,比如用C或C++实现。

2、在定义一个native方法时,并不提供实现体(比较像定义一个Java Interface),因为其实现体是由非Java语言在外面实现的

主要是因为JAVA无法对操作系统底层进行操作,但是可以通过jni(java native interface)调用其他语言来实现底层的访问。

PC寄存器

这块内存区域很小,它是当前线程所执行的字节码的行号指示器,

字节码解释器通过改变这个计数器的值来选取下一条需要执行的字节码指令。

如果执行的是一个Native方法, 那这个计数器是空的。

方法区

方法区(Method Area)同Java 堆,是各个线程共享的内存区域,用于存储虚拟机已经加载的类信息,常量,静态变量,即时编译器编译后的代码等数据。

在不同的JDK版本中,方法区中存储的数据是不一样的。

在JDK1.6及之前,运行时常量池是方法区的一个部分,同时方法区里面存储了类的元数据信息、静态变量、即时编译器编译后的代码(比如spring 使用IOC或者AOP创建bean时,或者使用cglib,反射的形式动态生成class信息等)等。

在JDK1.7及以后,JVM已经将运行时常量池从方法区中移了出来,在JVM堆开辟了一块区域存放常量池。

JVM堆和JVM栈是程序运行的关键,很有必要把他们的关系说清楚。

JVM栈是运行时的单位,而JVM堆是存储的单位。

JVM栈解决程序的运行问题,即程序如何执行,或者说如何处理数据;JVM堆解决的是数据存储的问题,即数据怎么放、放在哪儿。

在Java中一个线程就会相应有一个线程JVM栈与之对应,这点很容易理解,因为不同的线程执行逻辑有所不同,因此需要一个独立的线程JVM栈。而JVM堆则是所有线程共享的。JVM栈因为是运行单位,因此里面存储的信息都是跟当前线程(或程序)相关信息的。包括局部变量、程序运行状态、方法返回值等等;而JVM堆只负责存储对象信息。

JVM的堆被同一个JVM实例中的所有Java线程共享

三种JVM

HotSpot,oracle JRockit,IBM J9

JRockit是oracle发明的,用于其WebLogic服务器,IBM JVM是IBM发明的用于其Websphere服务器(所以在某行开发的时候,他们用的是IBM的JDK,因为他们使用的IBM的应用程序服务器Websphere,使用其他JDK可能存在兼容性问题)。

新生区、老年区、永久区

堆内存调优

默认情况系:分配的总内存是电脑的1/4,而初始化的内存是1/64

如果出现OOM错误,代表堆内存不够,这时候我们可以通过调整堆内存大小,来进行堆内存的调优

  • 手动修改JVM内存参数:-Xms1024m -Xmx1024m -XX:+PrintGCDetails

 

我们也可以使用JProfile来进行,错误定位,进而对该部分的代码进行优化

GC

主要的作用区域是堆和方法区

常用算法:

  1. 标记/清除算法

  2. 复制算法

  3. 标记整理算法

JMM

Java内存模型(Java Memory Model,JMM)JMM主要是为了规定了线程和内存之间的一些关系。根据JMM的设计,系统存在一个主内存(Main Memory),Java中所有变量都储存在主存中,对于所有线程都是共享的。每条线程都有自己的工作内存(Working Memory),工作内存中保存的是主存中某些变量的拷贝,线程对所有变量的操作都是在工作内存中进行,线程之间无法相互直接访问,变量传递均需要通过主存完成。

 

内存泄漏和内存溢出

内存泄漏与溢出的区别

  1. 内存泄漏是指分配出去的内存无法回收了。

  2. 内存溢出是指程序要求的内存,超出了系统所能分配的范围,从而发生溢出。比如用byte类型的变量存储10000这个数据,就属于内存溢出。

  3. 内存溢出是提供的内存不够;内存泄漏是无法再提供内存资源。

何时产生内存泄漏

  1. 静态集合类:在使用Set、Vector、HashMap等集合类的时候需要特别注意,有可能会发生内存泄漏。当这些集合被定义成静态的时候,由于它们的生命周期跟应用程序一样长,这时候,就有可能会发生内存泄漏。

    jvm中的内存溢出与内存泄露 - sunweiye - 博客园

    内存泄漏是指本应该被GC回收的无用对象没有被回收,导致的内存空间的浪费,当内存泄露严重时会导致OOM。Java内存泄露根本原因是:长生命周期的对象持有短生命周期对象的引用,尽管短生命周期对象已经不再需要,但是因为长生命周期对象持有它的引用而导致不能被GC回收。

  2. 监听器:在Java中,我们经常会使用到监听器,如对某个控件添加单击监听器addOnClickListener(),但往往释放对象的时候会忘记删除监听器,这就有可能造成内存泄漏。好的方法就是,在释放对象的时候,应该记住释放所有监听器,这就能避免了因为监听器而导致的内存泄漏。

  3. 各种连接:Java中的连接包括数据库连接、网络连接和io连接,如果没有显式调用其close()方法,是不会自动关闭的,这些连接就不能被GC回收而导致内存泄漏。一般情况下,在try代码块里创建连接,在finally里释放连接,就能够避免此类内存泄漏。

  4. 外部模块的引用:调用外部模块的时候,也应该注意防止内存泄漏。如模块A调用了外部模块B的一个方法,如:public void register(Object o)。这个方法有可能就使得A模块持有传入对象的引用,这时候需要查看B模块是否提供了去除引用的方法,如unregister()。这种情况容易忽略,而且发生了内存泄漏的话,比较难察觉,应该在编写代码过程中就应该注意此类问题。

  5. 单例模式:使用单例模式的时候也有可能导致内存泄漏。因为单例对象初始化后将在JVM的整个生命周期内存在,如果它持有一个外部对象(生命周期比较短)的引用,那么这个外部对象就不能被回收,而导致内存泄漏。如果这个外部对象还持有其它对象的引用,那么内存泄漏会更严重,因此需要特别注意此类情况。这种情况就需要考虑下单例模式的设计会不会有问题,应该怎样保证不会产生内存泄漏问题。

常见实例问题

思考:假如我们自己写了一个java.lang.String的类,我们是否可以替换调JDK本身的类?

答案是否定的。我们不能实现。为什么呢?我看很多网上解释是说双亲委托机制解决这个问题,其实不是非常的准确。因为双亲委托机制是可以打破的,你完全可以自己写一个classLoader来加载自己写的java.lang.String类,但是你会发现也不会加载成功,具体就是因为针对java.*开头的类,jvm的实现中已经保证了必须由bootstrap来加载。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JVM面试题 的相关文章

  • java中的csv到pdf文件

    我正在尝试获得一个csv文件解析为pdf 到目前为止我所拥有的内容附在下面 我的问题是这段代码最终出现在 pdf 中的文件在 csv 文件的第一行被截断 我不明白为什么 附示例 本质上我想要一个没有任何操作的 csv 文件的 pdf 版本
  • 如何在 Eclipse 中用阿拉伯语读写

    我在 eclipse 中编写了这段代码来获取一些阿拉伯语单词 然后打印它们 public class getString public static void main String args throws Exception PrintS
  • 由于连接超时,无法通过 ImageIO.read(url) 获取图像

    下面的代码似乎总是失败 URL url new URL http userserve ak last fm serve 126 8636005 jpg Image img ImageIO read url System out printl
  • 如何从另一个xml文件动态更新xml文件?

    我想从另一个 xml 文件更新 xml 文件 我使用了一个 xml 文件 如下所示 one xml
  • 有没有好的方法来解析用户代理字符串?

    我有一个Java接收模块User Agent来自最终用户浏览器的字符串的行为需要略有不同 具体取决于浏览器类型 浏览器版本甚至操作系统 例如 FireFox 7 0 Win7 Safari 3 2 iOS9 我明白了User Agent由于
  • Java 泛型/类型调度问题

    考虑以下程序 import java util List import java util ArrayList public class TypeTest public static class TypeTestA extends Type
  • Google Inbox 类似 RecyclerView 项目打开动画

    目前 我正在尝试实现 Google Inbox 例如RecyclerView行为 我对电子邮件打开动画很好奇 我的问题是 该怎么做 我的意思是 他们使用了哪种方法 他们用过吗ItemAnimator dispatchChangeStarti
  • 使用 Java 在浏览器中下载 CSV 文件

    我正在尝试在 Web 应用程序上添加一个按钮 单击该按钮会下载一个 CSV 文件 该文件很小 大小仅约 4KB 我已经制作了按钮并附加了一个侦听器 文件也准备好了 我现在唯一需要做的就是创建单击按钮时下载 csv 文件的实际事件 假设 fi
  • 如何将 XMP XML 块序列化为现有的 JPEG 图像?

    我有许多 JPEG 图像 其中包含损坏的 XMP XML 块 我可以轻松修复这些块 但我不确定如何将 固定 数据写回图像文件 我目前正在使用 JAVA 但我愿意接受任何能让这项任务变得容易的事情 这是目标关于 XMP XML 的另一个问题
  • Java替换特定字符

    这是我在这个网站上的第一个问题 所以我会尽量不要成为一个十足的菜鸟 我目前正在用java 创建刽子手游戏 所以我问你的问题是我们是否被赋予了 幽灵 这个词 并将 Ghost 替换为 hiddenWord ghost length for i
  • cucumber-junit-platform-engine 中的功能文件发现

    In cucumber junit我使用的库 CucumberOptions定义功能文件位置 package com mycompany cucumber import cucumber api CucumberOptions import
  • 想要开发像 Facebook 这样的网站 - 处理数百万个请求 - 高性能 [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我想用 Java 开发一个像 Fac
  • jmap - 组织和堆操作会给 jvm 带来开销吗?

    正如标题所述 需要多少开销jmap histo and jmap heap分别带到jvm 如果一个内存敏感的 Java 进程处于OutOfMemory 例如 大约 96 的堆已满 并且无法通过 full gc 清除 其中一项操作是否有可能将
  • 让JScrollPane控制多个组件

    对于我的应用程序 我正在设计一个脚本编辑器 目前我有一个JPanel其中包含另一个JPanel保存行号 位于左侧 以及JTextArea用于允许用户输入代码 位于右侧 目前 我已经实施了JScrollPane on the JTextAre
  • ExceptionHandler 不适用于 Throwable

    我们的应用程序是基于 Spring MVC 的 REST 应用程序 我正在尝试使用 ExceptionHandler 注释来处理所有错误和异常 I have ExceptionHandler Throwable class public R
  • struts 教程或示例

    我正在尝试在 Struts 中制作一个登录页面 这个想法是验证用户是否存在等 然后如果有错误 则返回到登录页面 错误显示为红色 典型的登录或任何表单页面验证 我想知道是否有人知道 Struts 中的错误管理教程 我正在专门寻找有关的教程 或
  • Java中获取集合的幂集

    的幂集为 1 2 3 is 2 3 2 3 1 2 1 3 1 2 3 1 假设我有一个Set在爪哇中 Set
  • 为什么 BufferedWriter 不写入文件?

    我有这个代码 String strings Hi You He They Tetrabenzene Caaorine Calorine File file new File G words txt FileWriter fWriter Bu
  • Spring Boot MSSQL Kerberos 身份验证

    目前在我的春季靴子中application properties文件中 我指定以下行来连接到 MSSql 服务器 spring datasource url jdbc sqlserver localhost databaseName spr
  • Java中有类似分支/跳转表的东西吗?

    Java有类似分支表或跳转表的东西吗 分支表或跳转表是 根据维基百科 http en wikipedia org wiki Branch table 用于描述使用分支指令表将程序控制 分支 转移到程序的另一部分 或可能已动态加载的不同程序

随机推荐

  • 【OpenGL】opengl shader内置变量和函数

    1 uint CreateShader enum type 创建空的shader object type VERTEX SHADER 2 void ShaderSource uint shader sizeicount const stri
  • 关于thinkphp union多表关联查询 后排序及分页实现

    遇到的问题 1 union后直接排序或分页报错 Incorrect usage of UNION and ORDER BY 2 fetchSql得到的查询语句是没有 括起来的 3 buildSql 得到的查询语句有 括起来的 例如 查询语句
  • typeScript面试必备之-通识一

    现在玩ts的前端越来越多 作为马上来临的春季招聘 前端的小伙伴你准备好了吗 ts越来越像java 更加规整 个人认为这是一个大趋势 Typescript 介绍 1 TypeScript 是由微软开发的一款开源的编程语言 2 TypeScri
  • java获取所有方法及注释_获取类的方法上的所有方法上的注解

    最近在加深注解这块的理解 很多框架都使用到了注解 直接上代码 注解的实现类 Anno java package com robot test import java lang annotation ElementType import ja
  • 《The Road Less Traveled》,心智成熟之旅

    少有人走的路 Scott Peck 规矩 人生苦海无边 人生不是享乐的过程 是解决一个个问题的过程 这个过程中我们会遇到越来越多的问题 我们要正视问题 而不是选择忽略 忽略问题不会使它消失 到后面也是要自己承担 通俗来说就是 现在所受的苦很
  • 梳理百年深度学习发展史-七月在线机器学习集训营助你把握深度学习浪潮

    作为机器学习最重要的一个分支 深度学习近年来发展迅猛 在国内外都引起了广泛的关注 然而深度学习的火热也不是一时兴起的 而是经历了一段漫长的发展史 接下来我们了解一下深度学习的发展历程 1 深度学习的起源阶段 图1 AI之父 马文 明斯基 1
  • 列表页曝光埋点实现

    列表页曝光埋点实现 以商品为例 要求 商品一半以上出现在视窗中时 上报该行的商品 快速滑动过去的商品不上报 滑动过程中如果一行商品一直未消失在视野中 一半以上 不能重复上报 滑出视野的商品 再次滑入视野时需要再次上报 分析 需要以下信息 商
  • Mybatis---resultMap详解

    目录 一 resultMap介绍 二 自定义映射关系 一 resultMap介绍 该标签的作用是自定义映射关系 Mybatis可以将数据库结果封装到对象中 是因为结果集和对象属性名相同 也就是你写的pojo类型的参数名和数据库的字段名相同
  • Your account has been blocked. fatal: Could not read from remote repository

    1 首先设置自己的账户 https blog csdn net qq 38125058 article details 81209667 2 然后 删除在git配置密码的文件下 home kevin ssh 删除别人的文件
  • Reactive Streams, flux, mono介绍之白话版

    目录 要解决的问题 解决原理 解决方法 发布者Publisher 订阅者Subscriber 订阅对象Subscription 处理者Processor 源码简析 spring中响应式流的应用 服务端技术栈 响应式Http客户端 服务端修改
  • NodeJs入门(一)

    1 process nextTick callback 它的功能是为事件循环设置一项任务 nodeJs会在下一个事件循环时调用callback Node js是单线程的 除了系统IO之外 在它的事件轮询过程中 同一时间只会处理一个事件 你可
  • windows server2016创建AD域账户并登录

    上篇介绍了Windows Server2016下安装配置AD域 查看文章请点这里 接下来介绍创建AD域账户并登录域账户的流程步骤 创建域账户 1 右键AD服务器 选择Active Directory管理中心 2 右键AD名称 选择新建 组织
  • TCP 通信流程

    1 TCP通信过程 TCP 是一个面向连接的 安全的 流式传输协议 这个协议是一个传输层协议 1 面向连接 是一个双向连接 通过三次握手完成 断开连接需要通过四次挥手完成 2 安全 tcp 通信过程中 会对发送的每一数据包都会进行校验 如果
  • Java中使用JDBC操作Postgresql

    目录 在Rocky Linux上安装postgresql 用IntelliJ创建JavaFx项目 画一个表格 建立数据库访问 在Rocky Linux上安装postgresql Rocky的仓库中自带了postgresql安装包 我们直接用
  • ffmpeg: error while loading shared libraries: libavdevice.so.57

    编译完ffmpeg后 在终端敲ffmpeg 反馈如下 ffmpeg error while loading shared libraries libavdevice so 57 cannot open shared object file
  • 在matlab中寻找曲线上离原点距离最近的点的坐标的思考

    syms y x linspace 2 2 200 n length x g for i 1 n a x i t vpa solve y 1 a 2 y 2 sin a cos y y 3 g g t end 对于这个代码主要是想算出对应x
  • 第六章 存储器层次结构 第一节 存储技术之磁盘存储

    磁盘能比RAM存储更大的信息 但是读取速度上比DRAM慢了10万倍 比SRAM慢了100万倍 1 磁盘构造 磁盘是由盘片 platter 构成 盘片中央有一个可以旋转的主轴 它使得盘片以固定的旋转速率旋转 每个盘片有两面或者称为表面 表面覆
  • JDK开发环境配置

    JRE Java Runtime Environment Java运行环境 用来运行JAVA程序 JDK Java Development Kit Java开发工具包 包含JRE JDK 是整个Java的核心 包括了Java运行环境 Jav
  • 深度神经网络加速库cuDNN简介

    深度神经网络加速库cuDNN简介 简介 NVIDIA CUDA深度神经网络库 cuDNN CUDA Deep Neural Network 是用于深度神经网络的 GPU 加速基元库 它提供了 DNN 应用程序中经常出现的例程的高度调整实现
  • JVM面试题

    JVM相关 jvm详解 GC 堆内存参数调优 春 的博客 CSDN博客 jvm堆内存调优 常见JVM面试题及答案整理 Java程序员 张凯的博客 CSDN博客 jvm面试题 JVM的模块 常见问题 JVM的理解 java8虚拟机和之前的变化