ARTS-WEEK-006

Algorithm:

70: Climbing Stairs (Easy)

167: Two Sum II - Input array is sorted (Easy)

120: Triangle (Medium)

经典动态规划,状态转移方程是自底向上,row[i] = row[i] + min(pre[i] + pre[i+1]),其中状态是底部终点到该点的累积值。注意不能贪心,因为局部最优的路径限制后面选择。

Review:

Medium: Understanding Java Memory Model

Baeldung: Guide to Java String Pool

Baeldung: Native Memory Tracking in JVM

JVM 内存管理相关的几篇文章,第一篇文章有一系列直观的结构图,对不同层次的结构进行展示和简单介绍,后面两篇文章对字符串池和其他非堆内存进行详细解读。一些概念容易混淆,如 Method Area 在内存结构图中不存在,这是因为它是逻辑概念,可以认为就是 Metaspace 或其中一部分。还有一种划分是堆内存和非堆内存,因为堆内存才是 JVM 替程序员进行自动管理的内存(对比 C 语言手动申请的),非堆内存也称为 Native Allocations,用来管理类型元信息、应用代码、JIT 生成代码、内部数据结构等部分。此外还有系统原生内存使用如 JNI 和 NIO 的直接内存,并不是 JVM 内存管理模型中的内容。

Tip:

使用 JCMD 分析 JVM 非堆内存使用

必须开启 XX:NativeMemoryTracking,注意如果使用 openjdk 需要安装 devel 包才有 jcmd、jstack 等工具。

#yum install java-1.8.0-openjdk-devel
java -Xmx128m -Xms128m -XX:NativeMemoryTracking=summary -XX:+UseG1GC -jar hello.jar

进程整体使用内存,RES:241M,SHR:16M,共 257M。

➜  ~ top -p 28697
top - 03:10:14 up 95 days,  9:13,  2 users,  load average: 0.00, 0.01, 0.00
Tasks:   1 total,   0 running,   1 sleeping,   0 stopped,   0 zombie
%Cpu(s):  6.2 us,  0.0 sy,  0.0 ni, 93.8 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  1008352 total,   188084 free,   398360 used,   421908 buff/cache
KiB Swap:   524284 total,   522992 free,     1292 used.   408088 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND
28697 root      20   0 2239484 241300  16464 S  0.0 23.9   0:24.84 java

jcmd 信息,第一行 Total 是下面所有明细的总和,其中 reserved 是指潜在使用的量(potentially use),committed 是指正在使用的量(using),这里是 277M,其中 Symbol 部分重复计算 10M,减去后依然比上面257M大 10M,暂时无法解释 TODO。

➜  ~ jcmd 28697 VM.native_memory
28697:

Native Memory Tracking:

Total: reserved=1566062KB, committed=283802KB
-                 Java Heap (reserved=131072KB, committed=131072KB)
                            (mmap: reserved=131072KB, committed=131072KB)
# Heap 128M = Xmx

-                     Class (reserved=1090748KB, committed=48008KB)
                            (classes #8368)
                            (malloc=1212KB #10492)
                            (mmap: reserved=1089536KB, committed=46796KB)
# Metaspace 已用 46M,注意总量始终 1G,不是 MaxMetaspaceSize

-                    Thread (reserved=35066KB, committed=35066KB)
                            (thread #35)
                            (stack: reserved=34912KB, committed=34912KB)
                            (malloc=114KB #201)
                            (arena=40KB #66)
# Threads stack 对应 Xss 1M,35个线程共35M,总量随着运行分配变化

-                      Code (reserved=251689KB, committed=12425KB)
                            (malloc=2089KB #4086)
                            (mmap: reserved=249600KB, committed=10336KB)
# Code Cache 已用 39M,总量 245M,对应-XX:ReservedCodeCacheSize

-                        GC (reserved=40430KB, committed=40430KB)
                            (malloc=2798KB #3878)
                            (mmap: reserved=37632KB, committed=37632KB)
# GC algorithms,G1 已用 39M,总量随着运行分配变化

-                  Compiler (reserved=162KB, committed=162KB)
                            (malloc=31KB #383)
                            (arena=131KB #5)

-                  Internal (reserved=2312KB, committed=2312KB)
                            (malloc=2280KB #11574)
                            (mmap: reserved=32KB, committed=32KB)
# DirectByteBuffer 等其他未分类部分,已用 2M,总量随着运行分配变化

-                    Symbol (reserved=12276KB, committed=12276KB)
                            (malloc=9103KB #88570)
                            (arena=3173KB #1)
# string tool and constant pool,从 JDK8 起应该在 Heap 中,总量随着运行分配变化

-    Native Memory Tracking (reserved=1874KB, committed=1874KB)
                            (malloc=8KB #91)
                            (tracking overhead=1866KB)

-               Arena Chunk (reserved=178KB, committed=178KB)
                            (malloc=178KB)

-                   Unknown (reserved=256KB, committed=0KB)
                            (mmap: reserved=256KB, committed=0KB)

Share:

Capital One: Go is Boring, And That’s Fantastic!

近期一篇很火热的文章,在 HN 上有300多讨论。作者借助 Go 语言一些特点,深入分析了为什么要依赖简单、可靠、容易理解的技术。主要论据有:

  • 性能再次重要起来,因为最近 10 年硬件发展遇到瓶颈
  • 尽早发现问题,Go 快速编译以及内置的 Test、Benchmarking、profiling 等工具使其比其他语言生态更容易做到
  • 内存很难管理,相比 Rust、Swift 这些半自动的、依然需要深入细节才能用好的方式,Go 有全自动的、性能也足够的自动内存管理。
  • 便于 Code Reviews 和 低沟通成本,Go 只有一种风格 go fmt,没有异常、AOP、继承、重载等复杂内容,可以清晰地知道调用什么代码,返回什么值,并且 Go 从发布之初到现在并没有重大语言变化,可以避免熔岩流反模式 lava flow anti-pattern
  • 最后,语言并不开发中的主要问题,流程、工具、测试、性能、长期维护这些更加重要。而 Go 使用 70 年代的那些设计理念(CSP 等)已经可以很好的解决这些问题。这与其他不断引入新特性的语言、以及一些新引入的语言相比更加乏味,但是使用一些全新的理念、未经充分测试的技术并不是建造可靠桥梁的最佳方法。
posted @ 2020-07-05 16:26  Jeff_p  阅读(140)  评论(0编辑  收藏  举报