Java核心技术面试精讲
杨晓峰
前Oracle首席工程师
立即订阅
43250 人已学习
课程目录
已完结 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核心技术面试精讲
登录|注册

第30讲 | Java程序运行在Docker等容器环境有哪些新问题?

杨晓峰 2018-07-14
如今,Docker 等容器早已不是新生事物,正在逐步成为日常开发、部署环境的一部分。Java 能否无缝地运行在容器环境,是否符合微服务、Serverless 等新的软件架构和场景,在一定程度上也会影响未来的技术栈选择。当然,Java 对 Docker 等容器环境的支持也在不断增强,自然地,Java 在容器场景的实践也逐渐在面试中被涉及。我希望通过专栏今天这一讲,能够帮你能做到胸有成竹。
今天我要问你的问题是,Java 程序运行在 Docker 等容器环境有哪些新问题?

典型回答

对于 Java 来说,Docker 毕竟是一个较新的环境,例如,其内存、CPU 等资源限制是通过 CGroup(Control Group)实现的,早期的 JDK 版本(8u131 之前)并不能识别这些限制,进而会导致一些基础问题:
如果未配置合适的 JVM 堆和元数据区、直接内存等参数,Java 就有可能试图使用超过容器限制的内存,最终被容器 OOM kill,或者自身发生 OOM。
错误判断了可获取的 CPU 资源,例如,Docker 限制了 CPU 的核数,JVM 就可能设置不合适的 GC 并行线程数等。
从应用打包、发布等角度出发,JDK 自身就比较大,生成的镜像就更为臃肿,当我们的镜像非常多的时候,镜像的存储等开销就比较明显了。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《Java核心技术面试精讲》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(10)

  • 东方
    cpu问题

    java 10之前: 手动设置jvm相关的选项,如:

        ParallelGCThreads
        ConcGCThreads
        G1ConcRefinementThreads
        CICompilerCount / CICompilerCountPerCPU

    java 10+: UseContainerSupport, 默认开启

    ------------------------------------------------------------------
    mem问题

    需关注这几个参数:

        Xmx: 1/4 * 物理内存
        MaxDirectMemorySize
            Xmx 未设置,物理内存
            Xmx 设置了, Xmx - S0(1/10 * Xmx) = 0.9 * Xmx # why? SurvivorRatio默认值8
        MaxPermSize: 默认64M
            [5.0+ 64 bit: 64M * 1.3 = 85M](http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html)
        MaxMetaspaceSize: -1,无限制

    --------------------------------
    java5/6/7/8u131-:务必设置上面提到的内存选项

      懒人可考虑,虽然也不准确
      java -Xmx`cat /sys/fs/cgroup/memory/memory.limit_in_bytes`

    java8u131+和java9+

    java 8u131+和java 9+-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap
    java 8u191+ UseContainerSupport默认开启,backported;java 9暂未backport这个feature

    java 10+: UseContainerSupport, 默认开启
    ------------------------------------------------------------------
    2018-07-24
    15
  • Harry陈祥
    老师您好。对于java8+docker的场景,docker的cpu 内存配额是可能动态变化和伸缩的, docker启动之前,不知道会被分配多大内存多少cpu,这种情况,应该怎么处理参数问题?
    还有一个问题是:docker hub里面有java各个版本的镜像,这些镜像是否已经对文中提到的问题都做了适配?我们在构建docker的时候,直接from java镜像,而不再设置java options 会不会有问题?
    2019-02-14
    3
  • sgl
    没有一种技术是万能的,需要理解技术的优点和不足,才能使用好它
    2018-09-28
    2
  • 大卫李
    MAXRAM这个参数好像是openjdk的,oracle jdk文档里没有找到

    作者回复: 可以试验一下,我在外面不好翻文档,但应该oracle jdk是有的,openjdk可以说是oracle jdk的子集

    2018-08-13
    2
  • 正是那朵玫瑰
    目前容器只跑了java和consul的client进程,consul占的内存很小,java进程被kill掉后,consul进程还在,我们的java进程被kill掉都是在没有流量进来的时候,不过您说的使用swap区的我没有设置,不知道有没有什么影响?
    2018-08-07
    2
  • 正是那朵玫瑰
    老师好,再描述下我们的场景,我们在线上环境的参数是:xmx1g,永久带256m,docker限制2.2g,其他并没有设置,我们也怀疑是不是堆外内存有问题,于是在准生产环境修改了参数进行测试,设置了MaxRAM1g,堆外故意设小128m,然后进行测试,用jconsole进行监控,我们观察到docker容器的内存不断飙升,只升不降,而jconsole监控的却很正常,young gc很频繁,但是full gc一次没有,当docker内存接近设置的2.2g时,java进程就基本要被kill掉了,没有任何内存溢出的异常!

    作者回复: 有排查其他进程吗?

    2018-08-07
    2
  • 卡斯瓦德
    1.老师听说docker里面只能用open-jdk使用oracle-jdk是有法律风险的,现在还是这样么? 2.jdk8设置了-xmx值小于docker设定的值就好,我们使用了docker-compose貌似这个只有设定内存使用上限,但是不超过这个值一般没问题,3.至于swap没有遇见过,能能讲何时会出现么,好预警下。 4.说个docker遇到相关问题就是jdbc驱动,貌似mysql5.14以前的驱动对docker不友好,如果select count(*) from table 这个值超过5000就会拿不到结果,而实际mysql-server端已经执行完毕并且sleep了

    作者回复: 1,法律问题我不知道不评价。个人建议看清事实,莫被人pr;2,是,出问题是极端情况,大部分场景并不复杂;3,具体我只注意到有人反应问题,但没有细节;回到一些常见实践,例如用G1,如果吞吐量不达标,通常调优堆大小设置为尽量大但又swap不发生,不然会影响吞吐量;4,很感谢提供这个案例,了解具体问题吗

    2018-07-14
    1
  • paopao
    年前就遇到了文中Gc线程数超过k8s设置核心数,jvm直接挂掉,看这文章印象深刻
    2019-06-20
  • 苦行僧
    目前在实际工作中还没有使用过docker

    作者回复: 嗯呢

    2019-02-05
  • 正是那朵玫瑰
    老师,有个问题想咨询下,我们现在迁移到docker环境,使用的还是java7,您说的那些参数我们都有设置,比如docker容器内存大小,最大堆内存,MaxRAM等,现在的问题是java应用在docker上跑一段时间就会被kill掉,我们监控内存情况是docker容器内存使用几乎被占满,但是jvm的内存使用却很正常,不知道为什么?老师能否指点下思路?

    作者回复: 容器内存限制,java xmx MaxDirectMemorySize之类都是多大?我们说过内存不只是堆,还有一些在堆外,需要留点儿余地;kill的时间点附近有收集什么信息没有

    2018-08-06
收起评论
10
返回
顶部