Java核心技术面试精讲
杨晓峰
前Oracle首席工程师
立即订阅
43260 人已学习
课程目录
已完结 43 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | 以面试题为切入点,有效提升你的Java内功
免费
模块一 Java基础 (14讲)
第1讲 | 谈谈你对Java平台的理解?
第2讲 | Exception和Error有什么区别?
第3讲 | 谈谈final、finally、 finalize有什么不同?
第4讲 | 强引用、软引用、弱引用、幻象引用有什么区别?
第5讲 | String、StringBuffer、StringBuilder有什么区别?
第6讲 | 动态代理是基于什么原理?
第7讲 | int和Integer有什么区别?
第8讲 | 对比Vector、ArrayList、LinkedList有何区别?
第9讲 | 对比Hashtable、HashMap、TreeMap有什么不同?
第10讲 | 如何保证集合是线程安全的? ConcurrentHashMap如何实现高效地线程安全?
第11讲 | Java提供了哪些IO方式? NIO如何实现多路复用?
第12讲 | Java有几种文件拷贝方式?哪一种最高效?
第13讲 | 谈谈接口和抽象类有什么区别?
第14讲 | 谈谈你知道的设计模式?
模块二 Java进阶 (16讲)
第15讲 | synchronized和ReentrantLock有什么区别呢?
第16讲 | synchronized底层如何实现?什么是锁的升级、降级?
第17讲 | 一个线程两次调用start()方法会出现什么情况?
第18讲 | 什么情况下Java程序会产生死锁?如何定位、修复?
第19讲 | Java并发包提供了哪些并发工具类?
第20讲 | 并发包中的ConcurrentLinkedQueue和LinkedBlockingQueue有什么区别?
第21讲 | Java并发类库提供的线程池有哪几种? 分别有什么特点?
第22讲 | AtomicInteger底层实现原理是什么?如何在自己的产品代码中应用CAS操作?
第23讲 | 请介绍类加载过程,什么是双亲委派模型?
第24讲 | 有哪些方法可以在运行时动态生成一个Java类?
第25讲 | 谈谈JVM内存区域的划分,哪些区域可能发生OutOfMemoryError?
第26讲 | 如何监控和诊断JVM堆内和堆外内存使用?
第27讲 | Java常见的垃圾收集器有哪些?
第28讲 | 谈谈你的GC调优思路?
第29讲 | Java内存模型中的happen-before是什么?
第30讲 | Java程序运行在Docker等容器环境有哪些新问题?
模块三 Java安全基础 (2讲)
第31讲 | 你了解Java应用开发中的注入攻击吗?
第32讲 | 如何写出安全的Java代码?
模块四 Java性能基础 (3讲)
第33讲 | 后台服务出现明显“变慢”,谈谈你的诊断思路?
第34讲 | 有人说“Lambda能让Java程序慢30倍”,你怎么看?
第35讲 | JVM优化Java代码时都做了什么?
模块5 Java应用开发扩展 (4讲)
第36讲 | 谈谈MySQL支持的事务隔离级别,以及悲观锁和乐观锁的原理和应用场景?
第37讲 | 谈谈Spring Bean的生命周期和作用域?
第38讲 | 对比Java标准NIO类库,你知道Netty是如何实现更高性能的吗?
第39讲 | 谈谈常用的分布式ID的设计方案?Snowflake是否受冬令时切换影响?
周末福利 (2讲)
周末福利 | 谈谈我对Java学习和面试的看法
周末福利 | 一份Java工程师必读书单
结束语 (1讲)
结束语 | 技术没有终点
Java核心技术面试精讲
登录|注册

第26讲 | 如何监控和诊断JVM堆内和堆外内存使用?

杨晓峰 2018-07-05
上一讲我介绍了 JVM 内存区域的划分,总结了相关的一些概念,今天我将结合 JVM 参数、工具等方面,进一步分析 JVM 内存结构,包括外部资料相对较少的堆外部分。
今天我要问你的问题是,如何监控和诊断 JVM 堆内和堆外内存使用?

典型回答

了解 JVM 内存的方法有很多,具体能力范围也有区别,简单总结如下:
可以使用综合性的图形化工具,如 JConsole、VisualVM(注意,从 Oracle JDK 9 开始,VisualVM 已经不再包含在 JDK 安装包中)等。这些工具具体使用起来相对比较直观,直接连接到 Java 进程,然后就可以在图形化界面里掌握内存使用情况。
以 JConsole 为例,其内存页面可以显示常见的堆内存各种堆外部分使用状态。
也可以使用命令行工具进行运行时查询,如 jstat 和 jmap 等工具都提供了一些选项,可以查看堆、方法区等使用数据。
或者,也可以使用 jmap 等提供的命令,生成堆转储(Heap Dump)文件,然后利用 jhat 或 Eclipse MAT 等堆转储分析工具进行详细分析。
如果你使用的是 Tomcat、Weblogic 等 Java EE 服务器,这些服务器同样提供了内存管理相关的功能。
另外,从某种程度上来说,GC 日志等输出,同样包含着丰富的信息。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《Java核心技术面试精讲》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(20)

  • Loading...
    今天阿里面试官问了我一个问题,我想了很久没想通,希望得到解答。为什么在标记垃圾的时候,需要stop the world

    作者回复: 对方问得有点含糊,不知道是否故意的,以cms为例,它有不同的mark: initial mark,conc mark, remark;conc时候不需要stw;其他需要短暂stw,这样引用关系才不变,另外效率也高

    2018-07-05
    2
    22
  • 铁拳阿牛
    -XX:NewRatio=value
    默认是2
    这里说是3面试官还说我记错了😣

    作者回复: 是我记错了,非常抱歉

    2018-07-18
    15
  • qpm
    班门弄斧,为老师补充一些关于Eden、两个Survivor的细节。
    1、大部分对象创建都是在Eden的,除了个别大对象外。
    2、Minor GC开始前,to-survivor是空的,from-survivor是由对象的。
    3、Minor GC后,Eden的存活对象都copy到to-survivor中,from-survivor的存活对象也复制to-survivor中。其中所有对象的年龄+1
    4、from-survivor清空,成为新的to-survivor,带有对象的to-survivor变成新的from-survivor。重复回到步骤2

    这是我看这边文章也有的疑问,通过查阅资料理解的,希望可以帮到其他同学

    作者回复: 非常感谢,下一章有配图详解,受制于一章的篇幅限制

    2018-07-07
    12
  • Bruce
    回答一下留言的问题,为什么标记的时候要stop the world,是为了避免在标记的时候又有对象在堆内生成,如果这个对象对其他未标记对象有引用,而这个时候由于gc而清理掉了未标记的对象,会有问题
    2019-03-14
    9
  • 北溟鱼汤
    java.lang.Runtime类有freeMemory()、totalMemory()等方法可以获取到jvm内存情况,看了一下是本地方法。

    作者回复: 是的

    2018-07-05
    8
  • blossomed
    老师,请问如何判断是否有内存泄露

    作者回复: 泄露可以对比不同时间点内存分配,一般看用户类型的分配情况,什么在增加。具体,比如用jmap -histo:live 多次快照,然后对比差异,或者用jmc之类profiling工具,都可以进行,对比会更加流畅一些

    2018-07-24
    5
  • ethan
    jar包发生冲突,如何定位是哪些jar包发生问题

    作者回复: 出错信息应该包含具体类的名字等信息;mvn依赖树

    2018-07-09
    2
  • clz1341521
    java.lang.Runtime类有freeMemory()、totalMemory()等方法可以获取到jvm内存情况,看了一下是本地方法。
    另外看到有同学说jmc,jconsole在linux上用不了的问题,其实1可以远程连接,2可以使用xshell

    作者回复: 不错

    2018-08-09
    1
  • 小卡向前冲
    使用javaagent可以获得对象的大小,但是引入时有点麻烦,查到的资料都说需要将代码放到jar包中,然后在启动时加上 -javaagent:jar包名。
    放不知道这个算不算。
    2018-07-11
    1
  • L.B.Q.Y
    jmx可以做到通过代码而不是工具去监控,其实jdk安装包的工具也是对jmx的一个薄层的封装。

    作者回复: 是的

    2018-07-05
    1
  • Hidden
    新对象都会创建在eden 和from 区域,当发生minor gc时 把这两个区域的存活对象复制到 to区域,然后清理eden 和from 区域,是这样理解吧

    作者回复: 有点区别,新对象大多是在eden,from是minor gc活下来copy的

    2018-07-05
    1
  • 三木子
    除了工具就是命令方式了,用过命令有vmstat,这属于linux的,主要监控cpu和内存使用情况,这里是服务器总体内存,所以这个命令不是非常直观。

    作者回复: 也是个办法;JMX之类内建的方式更直观一些

    2018-07-05
    1
  • szh
    Direct Buffer 的直接内存可以用MXBean查看,相关接口是java.lang.management.BufferPoolMXBean。在JConsole中的MBean java.nio.BufferPool可以看到。
    2019-07-31
  • Liu Xian
    分析过一次Android上的堆外内存OOM,是通过/proc/pid/maps文件里找到的线索。在Linux和Android上堆外内存基本都是通过操作系统的mmap接口从内存映射区分配的,所以maps文件也可以提供一些分析线索。
    2019-05-22
  • Jeffrey
    -Xms和-Xmx为什么很多文章都建议设置成一样大?有的解释是增长过程中会引发Full Gc,请问老师是这样么?
    2019-04-08
  • 陈道恒
    当然,也有特殊情况,我们知道普通的对象会被分配在 TLAB 上;如果对象较大,JVM 会试图直接分配在 Eden 其他位置上;如果对象太大,完全无法在新生代找到足够长的连续空闲空间,JVM 就会直接分配到老年代。
            杨老师你好,大对象直接分配到老年代,这里是指多大?有没什么衡量标准?

    作者回复: 这个要看具体什么GC,如果cms是PretenureSizeThreshold,G1本身就有homongous object的概念,region大小的一半

    2018-08-15
  • 代码狂徒
    老师,麻烦咨询下,像jconsole和jmc这些图形化的工具不适用于linux 服务器环境下使用吧,我试了下貌似并没有反应,所以对服务器环境内存监控或者问题跟踪,有什么好的工具呢?
    2018-07-22
  • 代码狂徒
    老师,麻烦咨询下,像jconsole和jmc这些图形化的工具不适用于linux 服务器环境下使用吧,我试了下貌似并没有反应,所以对服务器环境内存监控或者问题跟踪,有什么好的工具呢?

    作者回复: 可以remote连接的,看看文档或者网上的指南

    2018-07-22
  • 张玮(大圣)
    当然,也有特殊情况,我们知道普通的对象会被分配在 TLAB 上;如果对象较大,JVM 会试图直接分配在 Eden 其他位置上;如果对象太大,完全无法在新生代找到足够长的连续空闲空间,JVM 就会直接分配到老年代。

    这里的较大具体会分配到eden的哪个位置呢,请杨兄指教下

    作者回复: 看具体选择,比如G1 gc,会有单独的region放大对象,甚至有可能是占有不只一个region;所以,文章是个提醒,具体还是要看自己的需要去深入

    2018-07-07
  • 三木子
    还有一个就是jstat,可以实时查看gc信息,这个也还是没有工具直观,

    作者回复: 是的,文中简单提了下

    2018-07-05
收起评论
20
返回
顶部