• linqw
    2019-08-22
    尝试回答下课后习题,老师有空帮忙看下哦
    如果有一个微服务是处理大量的文本,感觉这种一般不会要求时延,大部分都会进行异步处理,更加注重服务的吞吐率,服务可以在更大的内存服务器进行部署,然后把新生代的eden设置的更大些,因为这些文本处理完不会再拿来复用,朝生夕灭,可以在新生代Minor GC,防止对象晋升到老年代,防止频繁的Major GC,如果晋升的对象过多大于老年代的连续内存空间也会有触发Full Gc,然后在这些处理文本的业务流程中,防止频繁的创建一次性的大对象,把文本对象做为业务流程直接传递下去,如果这些文本需要复用可以将他保存起来,防止频繁的创建。也为了保证服务的高可用,也需对服务做限流、负载、兜底的一些策略。

    作者回复: 思路非常清晰,赞👍

    
     28
  • leslie
    2019-08-22
    一路跟着老师学到现在我大致明白了老师想阐述什么或者说上次回答我的困惑时的答案了;其实老师是想传授:为何要用消息队列、如何使用、何种场景下使用其涉及什么知识我们应当如何把握它的使用。
            老师上次的回答提到程序不用太深:不过其实程序、网络还有今天的课程提及的内存管理-其实是计算机组成原理的东西,如何合理的去结合这些知识才是消息队列把握好的关键;就像老师今天留的题目其实就是需要程序的垃圾回收机制的知识和组成原理的内存管理的知识结合才能给出相应的正确答案,不知道是否可以这样理解老师今天的题目?
           同时在跟几位老师的课一起学习知识并梳理自己从业多年的知识体系:至少让我觉得之前对于课程的选择是正确的,至少从大的方面去理解了;老师其实是在授之与渔,而非简单的授之与鱼。
          期待老师的下节课:希望老师解答一下我对于问题方向上的理解是否正确,谢谢。

    作者回复: 我希望更给大家的,既能有鱼,先填饱肚子解决手上的问题,然后还能有渔,学到捕鱼的技能,受用终生。

    
     9
  • 亚洲舞王.尼古拉斯赵...
    2019-08-22
    通过一个对象池,池子里的对象大小是10k,每次请求申请对象,结束请求归还对象。另外提个意见,老师能在每次新课的时候讲述一下上一课提的问题的答案吗?
     4
     8
  • a、
    2019-08-22
    通过jstat 观察gc情况和分析gc日志,来合理分配堆内存,年轻代,年老代大小,尽量让对象在minor gc就能被回收,而不需要执行full gc。因为full gc执行速度慢,程序暂停时间就长
    
     6
  • godtrue
    2019-08-23
    课后思考及问题
    1:这个算法有一个最大问题就是,在执行标记和清除过程中,必须把进程暂停,否则计算的结果就是不准确的。这也就是为什么发生垃圾回收的时候,我们的程序会卡死的原因。后续产生了许多变种的算法,这些算法更加复杂,可以减少一些进程暂停的时间,但都不能完全避免暂停进程。
    对于这段有几个问题?
    1-1:进程必须暂停,是在标记阶段还是在清除阶段?还是两者都会?
    1-2:进程暂停这个实现过程是怎样的?暂停后需要再启动,这个又是一个怎样的过程?
    1-3:后面解释进程必须暂停的原因是为了使计算结果更加准确,我觉得好比打扫卫生,我一个房间一个房间来,也不耽误其他房间的事,是不是暂停是不必须的,其实 young gc 几乎不停的在发生,只有发生full gc 的时候性能才会大大降低?
    1-4:内存清除这个动作具体是怎么实现的?是电平复位?还是打上可以继续使用的标位?如果打标位这个该怎么打呢?一位一位的打?还是一个字节一个字节的打?更或者是一块一块的打?
    展开

    作者回复: A1: 标记阶段需要暂停,清除阶段一般是不需要的。

    A2:这个问题有点复杂,你可以参考一下:https://stackoverflow.com/questions/16558746/what-mechanism-jvm-use-to-block-threads-during-stop-the-world-pause

    A3:对于GC来说只有一个房间,你是没有办法分成多个完全独立的小房间的。 像java中的young gc就是为了缓解这个问题,而产生的变种算法,它可以减少FullGC的次数,但没有办法完全避免FullGC。

    A4:内存是按页为单位管理的,也就是一块一块的,对于JVM来说,它有一套复杂的数据结构来记录它管理的所有页面与对象引用之间的关系。所谓清除和移动对象,就是修改这个记录关系的数据结构。

     2
     4
  • Jxin
    2019-08-29
    需求:
    1.处理10kb的文本(文本存储和业务处理)
    2.进程不卡死(高响应服务不中断)


    分析:
    1.请求不可丢失,响应要快,允许业务处理有一定滞后性。
    2.发挥单机性能极限,但不越限导致卡顿或中断。

    方案:
    1.采用生产消费模式,接受到数据直接持久化,异步消费。为了实现数据积压,不丢失,可以走跨进程的实现,比如mq。
    2.压测文本落盘和文本业务处理两个进程的负载能力,调整其接入层线程池线程数,找到最高单机并发上限,设置令牌桶做限流。通过水平扩提高总请求负载力。落盘和业务处理两块根据并发负载力调整相对集群的节点比例。


    注:除非业务真有性能需求,不然千万别一个对象传到底。架设防腐层,业务解耦,对系统的扩展力很是重要。对于高速发展的项目(变化大且快),其价值远大于这么点性能提升。(先往易于演变的架构走,前期堆机器。真到业务量足够庞大,需要调优时再调优)
    展开
    
     3
  • 书策稠浊
    2019-08-22
    拿到文本,异步写入硬盘,给队列一个路径,另一个线程监控队列,一个个路径拿出来加载到内存一个个处理。
    
     3
  • 业余草
    2019-08-22
    除了方法论,还想要一个结合方法论的demo实现!
     1
     3
  • PeterLu
    2019-10-28
    简单整理下jvm的一些概念,帮大家回忆回忆这些理论哈哈
    垃圾回收算法:
    标记清除:效率较低,会产生内存碎片
    复制算法:将内存一分为二,通过不断将活着的对象移动到内存另一面,再清除这面,解决了效率低、内存碎片的问题,引来新的问题:内存一分为二代价太高
    标记-整理算法:先标记(过程跟标记清除一样)再将存活对象都向一端移动,清理掉端边界以外的内存。适用于老年代
    分代收集算法:将内存划分为几块,新生代采用复制算法,老年代采用标记-整理算法
    垃圾收集器:
    Serial收集器:新生代采用复制算法,会stop the world;老年代采用标记-整理算法,也会stop the world
    ParNew收集器:Serial收集器的多线程版本,其他一模一样
    Parallel Scavenge收集器:特点:可控制的吞吐量
    CMS收集器:特点:重视服务响应速度,降低GC停顿时间
    大致分为4个步骤
    初始标记
    并发标记
    重新标记
    并发清除
    会在初始标记和重新标记这两步stop the world
    G1收集器:特点:可预测的停顿,可以明确指定在一个长度为M毫秒的时间片段内,消耗在GC上的时间不得超过N毫秒
    G1的运作大致分为以下几步:
    初始标记
    并发标记
    最终标记
    筛选回收
    会在初始标记、最终标记、筛选回收时stop the world
    展开
    
     2
  • 笑傲流云
    2019-08-23
    老师,说下我的思路:1,jvm对字符串有优化,字符串是不可变对象,通过字符串常量池,可以复用一些字符串;2,文本10kb过大,是否可以拆分?建议分割文本,形成小对象直接在年轻代被垃圾回收,避免大对象直接进入老年代,引发频繁的full gc;3,Kafka底层存储机制大量使用了page cache,把子节码缓存在磁盘,避免大量对象引发gc问题。
    
     1
  • vi
    2019-08-22
    1. 使用对象池,重复使用对象,每次处理文件中的行数据,更新到利用的对象中
    2. 把对象外迁,使用中间件缓存对象,不被GC扫描到
     1
     1
  • 许童童
    2019-08-22
    我会考虑使用享元模式,预先分配10KB 左右的对象池,当请求进来时,从对象池中拿一个来使用,用完后,自己释放,以此来自己回收,复用这些对象,减少对象的创建,从而减少垃圾回收。
    
     1
  • 冰激凌的眼泪
    2019-08-22
    占用内存差不多的,是不是比较适合池化?

    作者回复: 是这样的。

    
     1
  • 广训
    2019-08-22
    接上一条,点击空白留言出去了,这个功能好尴尬。可以先看机器能给到的内存量和cpu消耗,看大约一秒钟可以处理多少文件。然后限流,可以把文件存本地,也可以存消息队列中,看资源来定。控制文件数量,虽然处理排队慢了,但不至于挂掉。

    作者回复: 那能否用本节课中学到的一些内存管理的方法来解决呢?

    
     1
  • 佳佳大魔王
    2019-08-22
    创建一个静态类型的字符串来存放这个文本,这样每次改变字符串的内容就好了,而不用gc他
     4
     1
  • 努力努力再努力
    2019-11-21
    老师,假如我有一个对象,这个对象作为接口的入参,但是前端在传值的时候,只传了部分字段,那么在申请内存空间的时候,这个对象是只申请传值了的这些对象所以占用的空间,还是所有属性占用的空间

    作者回复: 这个问题比较复杂,没有统一的答案,在不同的编程语言中处理都不太一样。

    一般面向对象的语言,比如Java这种,对象的属性如果是基本类型,它的内存空间会随着对象的创建就占用上了。如果属性也是一个对象,什么时候真正去申请内存,取决于你的代码中是在什么时候new出这个属性对象的。

    
    
  • 饭粒
    2019-11-05
    看评论也学习不少东西,jvm 差不多忘光了(泪
    
    
  • 张新国
    2019-10-30
    如果是有大量的临时对象,我觉得有两种办法:1增大新生代内存占比 2是不是可以开启逃逸分析 随线程退出从栈内存中直接回收
    
    
  • 成都小郭
    2019-09-19
    disruptor,一个高性能队列,也有这样对对象的优化处理..初始化队列长度之后,就会创建那么多个对象,新消息进来就给对象赋值,减少了很多对象创建和销毁的时间
    
    
  • 布小丫学编程
    2019-09-17
    10kb还是挺大的,会扔到mq队列中,然后通过固定线程池来一一处理每个文本。整体思路还是使用异步处理的机制。
    
    
我们在线,来聊聊吧