Java性能调优实战
刘超
金山软件西山居技术经理
立即订阅
7535 人已学习
课程目录
已完结 48 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | 怎样才能做好性能调优?
免费
模块一 · 概述 (2讲)
01 | 如何制定性能调优标准?
02 | 如何制定性能调优策略?
模块二 · Java编程性能调优 (10讲)
03 | 字符串性能优化不容小觑,百M内存轻松存储几十G数据
04 | 慎重使用正则表达式
05 | ArrayList还是LinkedList?使用不当性能差千倍
加餐 | 推荐几款常用的性能测试工具
06 | Stream如何提高遍历集合效率?
07 | 深入浅出HashMap的设计与优化
08 | 网络通信优化之I/O模型:如何解决高并发下I/O瓶颈?
09 | 网络通信优化之序列化:避免使用Java序列化
10 | 网络通信优化之通信协议:如何优化RPC网络通信?
11 | 答疑课堂:深入了解NIO的优化实现原理
模块三 · 多线程性能调优 (10讲)
12 | 多线程之锁优化(上):深入了解Synchronized同步锁的优化方法
13 | 多线程之锁优化(中):深入了解Lock同步锁的优化方法
14 | 多线程之锁优化(下):使用乐观锁优化并行操作
15 | 多线程调优(上):哪些操作导致了上下文切换?
16 | 多线程调优(下):如何优化多线程上下文切换?
17 | 并发容器的使用:识别不同场景下最优容器
18 | 如何设置线程池大小?
19 | 如何用协程来优化多线程业务?
20 | 答疑课堂:模块三热点问题解答
加餐 | 什么是数据的强、弱一致性?
模块四 · JVM性能监测及调优 (6讲)
21 | 磨刀不误砍柴工:欲知JVM调优先了解JVM内存模型
22 | 深入JVM即时编译器JIT,优化Java编译
23 | 如何优化垃圾回收机制?
24 | 如何优化JVM内存分配?
25 | 内存持续上升,我该如何排查问题?
26 | 答疑课堂:模块四热点问题解答
模块五 · 设计模式调优 (6讲)
27 | 单例模式:如何创建单一对象优化系统性能?
28 | 原型模式与享元模式:提升系统性能的利器
29 | 如何使用设计模式优化并发编程?
30 | 生产者消费者模式:电商库存设计优化
31 | 装饰器模式:如何优化电商系统中复杂的商品价格策略?
32 | 答疑课堂:模块五思考题集锦
模块六 · 数据库性能调优 (8讲)
33 | MySQL调优之SQL语句:如何写出高性能SQL语句?
34 | MySQL调优之事务:高并发场景下的数据库事务调优
35 | MySQL调优之索引:索引的失效与优化
36 | 记一次线上SQL死锁事故:如何避免死锁?
37 | 什么时候需要分表分库?
38 | 电商系统表设计优化案例分析
39 | 数据库参数设置优化,失之毫厘差之千里
40 | 答疑课堂:MySQL中InnoDB的知识点串讲
模块七 · 实战演练场 (4讲)
41 | 如何设计更优的分布式锁?
42 | 电商系统的分布式事务调优
43 | 如何使用缓存优化系统性能?
44 | 记一次双十一抢购性能瓶颈调优
结束语 (1讲)
结束语 | 栉风沐雨,砥砺前行!
Java性能调优实战
登录|注册

26 | 答疑课堂:模块四热点问题解答

刘超 2019-07-20
你好,我是刘超。
本周我们结束了“JVM 性能监测及调优”的学习,这一期答疑课堂我精选了模块四中 11 位同学的留言,进行集中解答,希望也能对你有所帮助。另外,我想为坚持跟到现在的同学点个赞,期待我们能有更多的技术交流,共同成长。

第 20 讲

很多同学都问到了类似“黑夜里的猫"问到的问题,所以我来集中回复一下。JVM 的内存模型只是一个规范,方法区也是一个规范,一个逻辑分区,并不是一个物理空间,我们这里说的字符串常量放在堆内存空间中,是指实际的物理空间。
文灏的问题和上一个类似,一同回复一下。元空间是属于方法区的,方法区只是一个逻辑分区,而元空间是具体实现。所以类的元数据是存放在元空间,逻辑上属于方法区。

第 21 讲

Liam 同学,目前 Hotspot 虚拟机暂时不支持栈上分配对象。W.LI 同学的留言值得参考,所以这里一同贴出来了。

第 22 讲

非常赞,Region 这块,Jxin 同学讲解得很到位。这里我再总结下 CMS 和 G1 的一些知识点。
CMS 垃圾收集器是基于标记清除算法实现的,目前主要用于老年代垃圾回收。CMS 收集器的 GC 周期主要由 7 个阶段组成,其中有两个阶段会发生 stop-the-world,其它阶段都是并发执行的。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《Java性能调优实战》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(13)

  • 疯狂咸鱼
    这是一门神课
    2019-09-02
    6
  • 💪😊
    java的垃圾回收使用的是复制算法和标记整理算法,这样对象的内存是变化的吧?那么引用它的栈上的地址也会变掉吗?如果是的话如果hashmap的key如果没有自己实现hashcode的话,是不是就会引起了内存泄漏和程序错乱

    作者回复: 是的,对象的引用也被指向新的地址。

    2019-07-22
    2
  • -W.LI-
    老师好!最近正好在看多线程编程指南。有个东西没搞明白。
    我自己写了个demo把所有线程都在临界区调用wait方法,wait方法后是sleep方法。我在主线程调用了notifyall(),在临界区内打印了所有线程的状态,notifyall()之前都是waiting,之后都是blocked。出了临界区之后又打印了一次,发现有一个是timed_waiting,别的还是blocked。
    从表现来看
    notifyall():wait->blocked
    调用notifyall()的线程出临界区释放锁锁:
    竞争到锁定blocked->runnable,别的还是blocked。
    之前老师说notifyall()在出临界区的时候调用比较好,可以防止被唤醒的阻塞状态线程,竞争不到锁再次阻塞。
    notifyall是本地方法看不到实现。我想确认下
    notifyall的逻辑是:唤醒waiting线程->尝试获取锁->获取不到blocked?
    还是:所有waiting状态线程->blocked状态进去锁池队列。(只有在有线程释放锁的时候(出临界区)才会从锁池队列拿一个线程尝试获取锁)。我比较倾向于第二种。没看源码希望老师帮忙解惑下,我特意翻了之前的课在那边也留言了,老师在这回复就好了谢谢老师

    作者回复: 对的,调用wait之后,会进入到WaitSet队列,当调用notify之后,默认策略是将其从WaitSet队列转至EntryList队列中,再尝试获取锁。

    2019-07-20
    2
  • Nu11PointerEx
    刘老师,我有个疑问,文中指出弱引用只能存活再下次GC之前,那假如线程在步骤A设置了threadlocal的值,然后需要在步骤B读出来,但是在AB之间发生了GC,这样会不会导致在步骤B中无法取到对应的值

    作者回复: 如果线程没有销毁,也就是说该key值依然存在引用,即使是弱引用,也不会被回收掉。

    2019-07-31
    1
  • Stalary
    老师,ThreadLocal使用的时候我存储了一些请求相关的东西,没有使用remove,但是一次请求结束就会自动释放掉了吧,是不是不会出现内存泄漏?还是没太明白出现内存泄漏的场景,线程不都是工作完就会释放掉了吗

    作者回复: 是的,如果我们的线程在使用ThreadLocal的set之后就立刻销毁了,此时之前set的线程的key值通过垃圾回收回收掉,此时value则会存在内存泄漏,而马上又有下一个线程使用ThreadLocal的set,则会清除之前key为null的value,这种情况下是不会出现内存泄漏的。

    也就是ThreadLocal的get(),set(),remove()的时候都会清除线程ThreadLocalMap里所有key为null的value。

    我们可以使用set之后,sleep下该线程,等待其他请求都一起使用完了set,这样很容易重现内存中的一部分对象无法回收掉。

    2019-07-28
    1
    1
  • 明翼
    超哥,有问题请教下:
    1)曾经被问到一个问题,就是java多线程分配内存的时候是如何控制并发冲突的那?
    2)能不能结合代码把java内存创建的过程讲一次,比如成员变量的引用是在哪里分配的(我理解是堆上),堆上还是栈上,临时变量那,通过这种整体的讲解会对我们印象比较深刻。
    2019-07-22
    1
  • Jxin
    抛砖引玉了,感谢老师的知无不尽。( ´◔‸◔`)
    2019-07-20
    1
  • nightmare
    老师cms和g1能不能加餐讲详细一点 因为互联网公司 cms和g1问的非常多

    作者回复: 好的,可以考虑。

    2019-07-20
    1
  • ty_young
    真的受益颇多,谢谢老师
    2019-10-27
  • godtrue
    我们的项目中ThreadLocal使用的蛮多的,使用原因是因为接口调用链长不想修改方法生命,但有些参数要透传就用ThreadLocal来透传参数。
    老师能否介绍一下题ThreadLocal的最佳实践?什么场景下会使用?有什么坑需要填?怎么规避风险?

    作者回复: 我们可以读取大部分读写中间件实现源码,可以发现ThreadLocal使用的最为频繁,通常是通过ThreadLocal来获取当前线程的操作类型来实现读写数据源的切换。

    在使用完之后实现remove操作,可以规避风险。

    2019-09-12
  • 风轻扬
    老师,jdk1.6的substring的内存泄漏问题。除了升级jdk版本,您有没有其他的办法。我在网上搜了一下,没有看到啥好办法

    作者回复: 升级版本就好了,现在基本都是基于1.8版本了

    2019-09-11
  • 风轻扬
    老师,jdk1.6的substring导致内存泄漏的问题。大字符串截取完之后,我们直接把原大字符串的引用置为null,可以解决这个内存泄漏的问题吗?

    作者回复: 不行,只是原来的引用置为null了,但堆中的字符串对象依然不会被回收掉

    2019-09-11
  • Mq
    老师threadlocal的entry不回收是因为value吗,另外我不理解jvm怎么知道我这次gc的时候key就可以回收,会不会出现我多次get的时候有一次就取不到了

    作者回复: 如果线程还存活,此时get是能获取到的,因为还存在强引用。如果线程生命周期已经结束,则ThreadLocal的线程本地变量将会失去引用,我们知道ThreadLocal是成员变量,如果key值没有设置为弱引用,则结束生命周期的线程变量依然会存在ThreadLocal中。
    所以,当线程生命周期结束,ThreadLocal的key又为了弱引用,key值就会在垃圾回收期被回收掉。

    2019-07-22
收起评论
13
返回
顶部