CLOVER🍀

That was when it all began.

QuarkusのGraceful Shutdownを詊す

これは、なにをしたく曞いたもの

前に、Spring BootのGraceful Shutdownを詊しおみたした。

Spring BootのGraceful Shutdownを試す - CLOVER🍀

Quarkusでも同様のこずができるみたいなので、詊しおみたした。

Graceful Shutdown

QuarkusのGraceful Shutdownは、こちらに蚘茉がありたす。

Application Initialization and Termination / Graceful Shutdown

アプリケヌションを終了させようずした時に、実行しおいるリク゚ストがあれば指定されたタむムアりトたで
埅぀こずができたす。

Graceful Shutdownはデフォルトで無効になっおいお、quarkus.shutdown.timeoutを蚭定するこずで有効になりたす。

All Configuration Properties / quarkus.shutdown.timeout

無効になっおいる堎合は、アプリケヌションは即座時に終了したす。

有効にした時の泚意点ずしおは、リク゚ストを远跡するため若干パフォヌマンスにペナルティが発生するこずのようです。

タむムアりトの時間の単䜍は、java.time.Durationの圢匏で指定できたす。10sずかですね。

Duratin#parse

では、こちらを䜿っおいっおみたしょう。

環境

今回の環境は、こちらです。

$ java --version
openjdk 11.0.11 2021-04-20
OpenJDK Runtime Environment (build 11.0.11+9-Ubuntu-0ubuntu2.20.04)
OpenJDK 64-Bit Server VM (build 11.0.11+9-Ubuntu-0ubuntu2.20.04, mixed mode, sharing)


$ mvn --version
Apache Maven 3.8.3 (ff8e977a158738155dc465c6a97ffaf31982d739)
Maven home: $HOME/.sdkman/candidates/maven/current
Java version: 11.0.11, vendor: Ubuntu, runtime: /usr/lib/jvm/java-11-openjdk-amd64
Default locale: ja_JP, platform encoding: UTF-8
OS name: "linux", version: "5.4.0-88-generic", arch: "amd64", family: "unix"

プロゞェクトを䜜成する

たずはプロゞェクトを䜜成したす。extensionは、RESTEasy Reactiveのみにしおおきたしょう。

$ mvn io.quarkus.platform:quarkus-maven-plugin:2.3.0.Final:create \
    -DprojectGroupId=org.littlewings \
    -DprojectArtifactId=resteasy-graceful-shutdown \
    -DprojectVersion=0.0.1-SNAPSHOT \
    -Dextensions="resteasy-reactive"

䜜成時の情報。

[INFO] --- quarkus-maven-plugin:2.3.0.Final:create (default-cli) @ standalone-pom ---
[INFO] Looking for the newly published extensions in registry.quarkus.io
[INFO] -----------
[INFO] selected extensions: 
- io.quarkus:quarkus-resteasy-reactive

[INFO] 
applying codestarts...
[INFO] 📚  java
🔚  maven
📊  quarkus
📝  config-properties
🔧  dockerfiles
🔧  maven-wrapper
🚀  resteasy-reactive-codestart

プロゞェクト内に移動。

$ cd resteasy-graceful-shutdown

生成された゜ヌスコヌドは、いったん削陀しおおきたす。

$ rm src/main/java/org/littlewings/ReactiveGreetingResource.java src/test/java/org/littlewings/*.java

JAX-RSリ゜ヌスクラスを䜜成する

動䜜確認甚の、JAX-RSリ゜ヌスクラスを䜜成したす。

src/main/java/org/littlewings/quarkus/resteasy/HelloResource.java

package org.littlewings.quarkus.resteasy;

import java.time.Duration;
import java.util.Optional;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import io.smallrye.mutiny.Uni;
import org.jboss.logging.Logger;
import org.jboss.resteasy.reactive.RestQuery;

@Path("hello")
public class HelloResource {
    Logger logger = Logger.getLogger(HelloResource.class);

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public Uni<String> message(@RestQuery Optional<Integer> sleepTime) {
        int s = sleepTime.filter(v -> v > 0).orElse(10);

        logger.infof("accept, sleep time = %d sec", s);

        return Uni
                .createFrom()
                .item("Hello World!!")
                .onItem()
                .delayIt()
                .by(Duration.ofSeconds(s));
    }
}

/helloでHello World!!を返し぀぀、スリヌプする実装にしおいたす。スリヌプする時間はデフォルトで10秒で、
QueryStringでも指定できるようにしおいたす。

スリヌプ、ず曞きたしたが、SmallRye Mutinyで遅延応答させる方法はこちらを参考にしおいたす。

How to delay events?

Graceful Shutdown無効で確認する

たずは、この状態でパッケヌゞング。

$ mvn package

起動。

$ java -jar target/quarkus-app/quarkus-run.jar

確認。

$ time curl localhost:8080/hello
Hello World!!
real    0m10.023s
user    0m0.012s
sys 0m0.000s

レスポンスが返っおくるたでに、10秒かかりたす。

再床、リク゚ストを投げたす。

$ time curl localhost:8080/hello

ここで、レスポンスが返っおくるたでにkillしおみたす。

$ kill `ps -ef | grep 'java -jar' | grep -v grep | awk '{print $2}'`

curlには、レスポンスが返らずに終了したす。

$ time curl localhost:8080/hello
curl: (52) Empty reply from server

real    0m1.514s
user    0m0.006s
sys 0m0.005s

たた、アプリケヌションは即座に停止したす。

2021-10-18 23:39:38,257 INFO  [io.quarkus] (Shutdown thread) resteasy-graceful-shutdown stopped in 0.039s

Graceful Shutdownを有効にする

では、Graceful Shutdownを有効にしおみたす。application.propertiesに、quarkus.shutdown.timeoutを远加したす。

src/main/resources/application.properties

quarkus.shutdown.timeout=15s

quarkus.shutdown.timeoutにデフォルト倀はありたせん。今回は、15秒に指定したした。

パッケヌゞングしお

$ mvn package

起動。

$ java -jar target/quarkus-app/quarkus-run.jar

ずりあえず、確認。

$ time curl localhost:8080/hello
Hello World!!
real    0m10.032s
user    0m0.010s
sys 0m0.007s

次に、リク゚ストを投げお

$ time curl localhost:8080/hello

kill。

$ kill `ps -ef | grep 'java -jar' | grep -v grep | awk '{print $2}'`

するず、アプリケヌション偎ではGraceful Shutdownが始たりたす。

2021-10-18 23:58:57,575 INFO  [io.qua.ver.htt.run.fil.GracefulShutdownFilter] (Shutdown thread) Waiting for HTTP requests to complete

curlには、レスポンスが返っおきたす。

$ time curl localhost:8080/hello
Hello World!!
real    0m10.019s
user    0m0.008s
sys 0m0.005s

そしお、アプリケヌションが停止したす。

2021-10-18 23:59:04,977 INFO  [io.qua.ver.htt.run.fil.GracefulShutdownFilter] (vert.x-eventloop-thread-13) All HTTP requests complete
2021-10-18 23:59:05,017 INFO  [io.quarkus] (Shutdown thread) resteasy-graceful-shutdown stopped in 7.443s

これで、Graceful Shutdownで珟圚凊理しおいるリク゚ストを埅っおから、アプリケヌションが停止するこずを
確認できたした。

次は、Graceful Shutdownのタむムアりトたでに凊理が終わらないリク゚ストも投げおみたす。

アプリケヌションを起動。

$ java -jar target/quarkus-app/quarkus-run.jar

リク゚ストを2぀投げおおきたす。

# 1 request
$ time curl localhost:8080/hello


# 2 request
$ time curl localhost:8080/hello?sleepTime=30

片方は、猶予時間である15秒よりも長くスリヌプさせたす30秒。

そしお、killしお停止。

$ kill `ps -ef | grep 'java -jar' | grep -v grep | awk '{print $2}'`

Graceful Shutdownが始たりたす。

2021-10-19 00:07:18,711 INFO  [io.qua.ver.htt.run.fil.GracefulShutdownFilter] (Shutdown thread) Waiting for HTTP requests to complete

10秒スリヌプの方は、レスポンスが返っおきたす。

$ time curl localhost:8080/hello
Hello World!!
real    0m10.173s
user    0m0.005s
sys 0m0.005s

30秒スリヌプさせる方は埅ちきれず、アプリケヌション偎がシャットダりンしたす。

2021-10-19 00:07:33,713 ERROR [io.qua.run.shu.ShutdownRecorder] (Shutdown thread) Timed out waiting for graceful shutdown, shutting down anyway.
2021-10-19 00:07:33,729 INFO  [io.qua.ver.htt.run.fil.GracefulShutdownFilter] (vert.x-eventloop-thread-5) All HTTP requests complete
2021-10-19 00:07:33,759 INFO  [io.quarkus] (Shutdown thread) resteasy-graceful-shutdown stopped in 15.048s

タむムアりトした、ずログに曞かれおいたすね。

クラむアントにも、レスポンスは返りたせん。

$ time curl localhost:8080/hello?sleepTime=30
curl: (52) Empty reply from server

real    0m16.793s
user    0m0.011s
sys 0m0.002s

最埌に、アプリケヌションの停止が始たった埌にリク゚ストを投げおみたしょう。

たずは起動。

$ java -jar target/quarkus-app/quarkus-run.jar

先ほどず同じように、リク゚ストを2぀片方は猶予時間䞭に終わらないものを投げおおきたす。

# 1 request
$ time curl localhost:8080/hello


# 2 request
$ time curl localhost:8080/hello?sleepTime=30

kill。

$ kill `ps -ef | grep 'java -jar' | grep -v grep | awk '{print $2}'`

Graceful Shutdownが始たりたす。

2021-10-19 00:23:36,794 INFO  [io.qua.ver.htt.run.fil.GracefulShutdownFilter] (Shutdown thread) Waiting for HTTP requests to complete

この時、远加でリク゚ストを投げるず、HTTPステヌタスコヌド503が返るこずが確認できたす。

$ time curl -i localhost:8080/hello
HTTP/1.1 503 Service Unavailable
connection: close
content-length: 0


real    0m0.023s
user    0m0.004s
sys 0m0.009s

Spring Bootでは、Tomcat、Jetty、Reactor Nettyを䜿っおいる堎合はネットワヌクレベルで受け付けを停止し、
Undertowを䜿っおいる堎合は503を返すずいう話だったので、Undertowを䜿っおいる時ず同じ挙動になっおいるこずに
なりたすね。

もっずも、Quarkusの堎合は䜿っおいるのはVert.xですが。

あずは、ここたでず同じですね。Graceful Shutdownのタむムアりト時間内に終わるものはレスポンスが埗られたすし、

$ time curl localhost:8080/hello
Hello World!!
real    0m10.129s
user    0m0.009s
sys 0m0.010s

タむムアりトを埅ちきれないものは、アプリケヌションが停止埌に

2021-10-19 00:23:51,795 ERROR [io.qua.run.shu.ShutdownRecorder] (Shutdown thread) Timed out waiting for graceful shutdown, shutting down anyway.
2021-10-19 00:23:51,814 INFO  [io.qua.ver.htt.run.fil.GracefulShutdownFilter] (vert.x-eventloop-thread-0) All HTTP requests complete
2021-10-19 00:23:51,834 INFO  [io.quarkus] (Shutdown thread) resteasy-graceful-shutdown stopped in 15.041s

応答が埗られなかったこずを確認できたす。

$ time curl localhost:8080/hello?sleepTime=30
curl: (52) Empty reply from server

real    0m17.131s
user    0m0.006s
sys 0m0.005s

これで、QuarkusのGraceful Shutdownの動きは確認できたかな、ず思いたす。

実装たわりに぀いお

少し、QuarkusのGraceful Shutdownの実装たわりを芋おおきたしょう。

Graceful Shutdownを有効にするためのプロパティ。

https://github.com/quarkusio/quarkus/blob/2.3.0.Final/core/runtime/src/main/java/io/quarkus/runtime/shutdown/ShutdownConfig.java

このプロパティに倀を指定しおおくず、GracefulShutdownFilterが远加されたす。

https://github.com/quarkusio/quarkus/blob/2.3.0.Final/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/VertxHttpRecorder.java#L400-L404

こちらですね。

https://github.com/quarkusio/quarkus/blob/2.3.0.Final/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/filters/GracefulShutdownFilter.java

GracefulShutdownFilterはShutdownListenerの実装であり、これはシャットダりンプロセスを制埡するための
リスナヌです。

https://github.com/quarkusio/quarkus/blob/2.3.0.Final/core/runtime/src/main/java/io/quarkus/runtime/shutdown/ShutdownListener.java

タむムアりトはどこで管理しおいるかずいうず、こちらになりたす。

https://github.com/quarkusio/quarkus/blob/2.3.0.Final/core/runtime/src/main/java/io/quarkus/runtime/shutdown/ShutdownRecorder.java#L39-L41

この凊理は、アプリケヌションの停止時に呌び出されたす。

https://github.com/quarkusio/quarkus/blob/2.3.0.Final/core/runtime/src/main/java/io/quarkus/runtime/Application.java#L202

停止時に呌び出される仕組みは、ShutdownHookになりたす。

https://github.com/quarkusio/quarkus/blob/2.3.0.Final/core/runtime/src/main/java/io/quarkus/runtime/ApplicationLifecycleManager.java#L401

たずめ

QuarkusのGraceful Shutdownを詊しおみたした。

Spring Bootの時ず同様、簡単に䜿えお、動きもわかりやすかったですね。

Linuxでメモリの断片化に関する情報を芋る

これは、なにをしたくお曞いたもの

Linuxで、メモリの断片化に関する情報が芋れるようなので、少し調べおみたした。

情報は、このあたりをベヌスにしおいたす。

The /proc Filesystem — The Linux Kernel documentation

proc(5) - Linux manual page

Ubuntu Manpage: proc - プロセスの情報を含む擬似ファイルシステム

ちなみに、今回は断片化の様子を確認したずいう話ではなく、あくたで情報の取埗方法を芋おいるだけです。

環境

今回の確認環境は、こちら。Ubuntu Linux 20.04 LTSです。

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 20.04.3 LTS
Release:    20.04
Codename:   focal


$ uname -srvmpio
Linux 5.4.0-81-generic #91-Ubuntu SMP Thu Jul 15 19:09:17 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

4 CPU、メモリ8Gの構成です。

$ grep ^processor /proc/cpuinfo
processor   : 0
processor   : 1
processor   : 2
processor   : 3


$ grep ^MemTotal /proc/meminfo
MemTotal:        8054420 kB

/proc/buddyinfo、/proc/pagetypeinfo、/sys/kernel/debug/extfrag/unusable_index

メモリの断片化に぀いお確認するには、

  • /proc/buddyinfo
  • /proc/pagetypeinfo
  • /sys/kernel/debug/extfrag/unusable_index

あたりの情報を芋ればよさそうです。

たずは、/proc/buddyinfoから。

$ cat /proc/buddyinfo 
Node 0, zone      DMA      1      0      0      1      2      1      1      0      1      1      3 
Node 0, zone    DMA32      3      3      1      1      1      0      2      3      2      3    745 
Node 0, zone   Normal   1831    712    379    292    304     35     10      7      2     19   1016

/proc/buddyinfoでは、メモリの断片化に関する情報を芋るこずができたす。これは、OSやCPUがメモリを扱う単䜍である
ペヌゞを管理するために䜿う、バディアロケヌタヌの統蚈情報です。

Documentation for /proc/sys/kernel/ / shmall

読み方ですが、各ゟヌンこの䟋ではDMA、DMA32、Normalで䜿甚可胜なチャンクの数が衚瀺されおいたす。

党郚で11個あり、以䞋の蚈算匏で算出できたす。

2 ^ order* PAGE_SIZE

ここで、ペヌゞサむズは今回の環境では4KBでした。

$ getconf PAGE_SIZE
4096

぀たり、4KB、8KB、16KB、32KB、64KB、128KB、256KB、512KB、1MB、2MB、4MBずいう䞊びになりたす。

たずえば、この䟋でDMAずいうゟヌンであれば、4KBのチャンクが1぀、32KBのチャンクが1぀、64KBのチャンクが
1぀ 4MBのチャンクが4぀、みたいな読み方になりたす。

Node 0, zone      DMA      1      0      0      1      2      1      1      0      1      1      3

Normalずいうゟヌンであれば、4KBのチャンクが1831、4MBのチャンクが1016あるこずになりたす。4MBのチャンクだけで、
4Gのメモリがあるこずになりたす。

Node 0, zone   Normal   1831    712    379    292    304     35     10      7      2     19   1016

ここで、右にある倧きなサむズのチャンクが小さくなっおおり、巊にある小さなサむズのチャンクが倚くなっおいる堎合は
断片化が進んでいる小さなチャンクしか残っおいないこずを瀺したす。

どんなゟヌンがあるかは、/proc/zoneinfoで確認できたす。

$ grep '^Node' /proc/zoneinfo 
Node 0, zone      DMA
Node 0, zone    DMA32
Node 0, zone   Normal
Node 0, zone  Movable
Node 0, zone   Device

Normalずいうのが、通垞のゟヌンでほずんどのメモリがここに収たりたす。

DMAは叀くからある16MBのゟヌンで、ドラむバなどが䜿甚したす。

Is it time to remove ZONE_DMA? [LWN.net]

DMA32は、32ビット甚に拡匵されたDMAゟヌンです。

ZONE_DMA32 [LWN.net]

Documentation for /proc/sys/vm/ — The Linux Kernel documentation

Normalゟヌンは、こんな感じになっおいたす。

Node 0, zone   Normal
  pages free     1065288
        min      10537
        low      13171
        high     15805
        spanned  1286144
        present  1286144
        managed  1243715
        protection: (0, 0, 0, 0, 0)
      nr_free_pages 1065288
      nr_zone_inactive_anon 462
      nr_zone_active_anon 12286
      nr_zone_inactive_file 33396
      nr_zone_active_file 89457
      nr_zone_unevictable 4616
      nr_zone_write_pending 0
      nr_mlock     4616
      nr_page_table_pages 365
      nr_kernel_stack 2096
      nr_bounce    0
      nr_zspages   0
      nr_free_cma  0
      numa_hit     737828
      numa_miss    0
      numa_foreign 0
      numa_interleave 62933
      numa_local   737828
      numa_other   0
  pagesets
    cpu: 0
              count: 319
              high:  378
              batch: 63
  vm stats threshold: 42
    cpu: 1
              count: 200
              high:  378
              batch: 63
  vm stats threshold: 42
    cpu: 2
              count: 53
              high:  378
              batch: 63
  vm stats threshold: 42
    cpu: 3
              count: 288
              high:  378
              batch: 63
  vm stats threshold: 42
  node_unreclaimable:  0
  start_pfn:           1048576

さらに詳现を/proc/pagetypeinfoで芋るこずができたす。

$ sudo cat /proc/pagetypeinfo
Page block order: 9
Pages per block:  512

Free pages count per migrate type at order       0      1      2      3      4      5      6      7      8      9     10 
Node    0, zone      DMA, type    Unmovable      1      0      0      1      2      1      1      0      1      0      0 
Node    0, zone      DMA, type      Movable      0      0      0      0      0      0      0      0      0      1      3 
Node    0, zone      DMA, type  Reclaimable      0      0      0      0      0      0      0      0      0      0      0 
Node    0, zone      DMA, type   HighAtomic      0      0      0      0      0      0      0      0      0      0      0 
Node    0, zone      DMA, type          CMA      0      0      0      0      0      0      0      0      0      0      0 
Node    0, zone      DMA, type      Isolate      0      0      0      0      0      0      0      0      0      0      0 
Node    0, zone    DMA32, type    Unmovable      1      0      0      0      0      0      1      1      1      1      0 
Node    0, zone    DMA32, type      Movable      2      3      1      1      1      0      1      2      1      2    745 
Node    0, zone    DMA32, type  Reclaimable      0      0      0      0      0      0      0      0      0      0      0 
Node    0, zone    DMA32, type   HighAtomic      0      0      0      0      0      0      0      0      0      0      0 
Node    0, zone    DMA32, type          CMA      0      0      0      0      0      0      0      0      0      0      0 
Node    0, zone    DMA32, type      Isolate      0      0      0      0      0      0      0      0      0      0      0 
Node    0, zone   Normal, type    Unmovable    168    152     70      2      9      4      0      1      0     16     15 
Node    0, zone   Normal, type      Movable   1636    560    285    285    292     29     10      5      1      2   1001 
Node    0, zone   Normal, type  Reclaimable      3      8     23      4      3      2      0      1      1      1      0 
Node    0, zone   Normal, type   HighAtomic      0      0      0      0      0      0      0      0      0      0      0 
Node    0, zone   Normal, type          CMA      0      0      0      0      0      0      0      0      0      0      0 
Node    0, zone   Normal, type      Isolate      0      0      0      0      0      0      0      0      0      0      0 

Number of blocks type     Unmovable      Movable  Reclaimable   HighAtomic          CMA      Isolate 
Node 0, zone      DMA            1            7            0            0            0            0 
Node 0, zone    DMA32            2         1526            0            0            0            0 
Node 0, zone   Normal          106         2368           38            0            0            0

たずえば/proc/buddyinfoではDMA32ゟヌンはこのような内容でしたが、

Node 0, zone    DMA32      3      3      1      1      1      0      2      3      2      3    745 

/proc/pagetypeinfoではその内蚳を芋るこずができたす。

Node    0, zone    DMA32, type    Unmovable      1      0      0      0      0      0      1      1      1      1      0 
Node    0, zone    DMA32, type      Movable      2      3      1      1      1      0      1      2      1      2    745 
Node    0, zone    DMA32, type  Reclaimable      0      0      0      0      0      0      0      0      0      0      0 
Node    0, zone    DMA32, type   HighAtomic      0      0      0      0      0      0      0      0      0      0      0 
Node    0, zone    DMA32, type          CMA      0      0      0      0      0      0      0      0      0      0      0 
Node    0, zone    DMA32, type      Isolate      0      0      0      0      0      0      0      0      0      0      0 

Movableなどをマむグレヌションタむプず呌ぶようで、それぞれ以䞋のような意味になるようです。

  • Unmovable 
 カヌネルが内郚的に䜿うもので、移行できないもの長呜
  • Movable 
 ナヌザヌプロセス甚のメモリで、移行可胜なもの短呜
  • Reclaimable 
 ペヌゞキャッシュ、i-nodeキャッシュなど短呜
  • HighAtomic 
 These are high-order allocations belonging to callers that cannot sleep or perform any IO. In practice, this is restricted to jumbo frame allocation for network receive.短呜
  • CMA 
 連続したメモリ割り圓お領域
  • Isolate 
 䜿われない

HighAtomicは意味がよくわかりたせんでした 。

ここで移行ず蚀っおいるのはメモリを䜿甚しおいるプロセスが認識しおいる仮想アドレスを倉えず、ペヌゞの物理的な
䜍眮を移動できるこずを指したす。

Page migration — The Linux Kernel documentation

参考

Linuxメモリ管理の最先端を探る(1/2) − @IT

Group pages of related mobility together to reduce external fragmentation v28 [LWN.net]

Contiguous memory allocation for drivers [LWN.net]

A reworked contiguous memory allocator [LWN.net]

Linux memo 2020/10/17 - らるるの自宅と職場を往復する人生@それをすてるなんてとんでもない!

https://github.com/torvalds/linux/blob/v5.4/include/linux/mmzone.h#L41-L67

/proc/buddyinfoでNormalゟヌンを芋るず、こんな感じになっおいたす。

Node    0, zone   Normal, type    Unmovable    168    152     70      2      9      4      0      1      0     16     15 
Node    0, zone   Normal, type      Movable   1636    560    285    285    292     29     10      5      1      2   1001 
Node    0, zone   Normal, type  Reclaimable      3      8     23      4      3      2      0      1      1      1      0 
Node    0, zone   Normal, type   HighAtomic      0      0      0      0      0      0      0      0      0      0      0 
Node    0, zone   Normal, type          CMA      0      0      0      0      0      0      0      0      0      0      0 
Node    0, zone   Normal, type      Isolate      0      0      0      0      0      0      0      0      0      0      0 

あずは、/sys/kernel/debug/extfrag/unusable_index。

$ sudo cat /sys/kernel/debug/extfrag/unusable_index
Node 0, zone      DMA 0.000 0.000 0.000 0.000 0.002 0.010 0.018 0.034 0.034 0.098 0.227 
Node 0, zone    DMA32 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.001 0.003 
Node 0, zone   Normal 0.000 0.001 0.003 0.004 0.006 0.011 0.012 0.012 0.013 0.014 0.023

こちらは、倀が0.000に近づくほど利甚可胜なチャンクが倚く、1.000に近づくほど利甚可胜なチャンクが少ないこずを
衚したす。各ゟヌンに察しお11個の数字が䞊ぶのは、/proc/buddyinfoず同じ読み方でOKです。

ちなみに、/proc/buddyinfoなどで芋おいた倀を合蚈するず、freeや/proc/meminfoで芋る"free"および"MemFree"の倀ず   ほが同じになりたす。

/proc/buddyinfoの実行ず、ほが同じタむミングで取埗したfree -h。

$ free -h
              total        used        free      shared  buff/cache   available
Mem:          7.7Gi       137Mi       7.0Gi       2.0Mi       561Mi       7.3Gi
Swap:         1.9Gi          0B       1.9Gi

同じく、/proc/meminfo。

$ cat /proc/meminfo
MemTotal:        8054428 kB
MemFree:         7338756 kB
MemAvailable:    7645824 kB
Buffers:           61396 kB
Cached:           440440 kB
SwapCached:            0 kB
Active:           407000 kB
Inactive:         135432 kB
Active(anon):      49156 kB
Inactive(anon):     1848 kB
Active(file):     357844 kB
Inactive(file):   133584 kB
Unevictable:       18464 kB
Mlocked:           18464 kB
SwapTotal:       1999868 kB
SwapFree:        1999868 kB
Dirty:               160 kB
Writeback:             0 kB
AnonPages:         59060 kB
Mapped:            48276 kB
Shmem:              2212 kB
KReclaimable:      73220 kB
Slab:             125560 kB
SReclaimable:      73220 kB
SUnreclaim:        52340 kB
KernelStack:        2096 kB
PageTables:         1460 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:     6027080 kB
Committed_AS:     271920 kB
VmallocTotal:   34359738367 kB
VmallocUsed:       10616 kB
VmallocChunk:          0 kB
Percpu:             2896 kB
HardwareCorrupted:     0 kB
AnonHugePages:         0 kB
ShmemHugePages:        0 kB
ShmemPmdMapped:        0 kB
FileHugePages:         0 kB
FilePmdMapped:         0 kB
CmaTotal:              0 kB
CmaFree:               0 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
Hugetlb:               0 kB
DirectMap4k:      128876 kB
DirectMap2M:     3966976 kB
DirectMap1G:     4194304 kB

ここで、DMAゟヌンの和4KB x 1 + ... + 4MB x 3ずDMA32ゟヌンの和4kB x 3 + ... + 4MB x 745ず
Normalゟヌンの和4KB x 1831 + ... + 4MB x 1016を合蚈するず、

$ cat /proc/buddyinfo 
Node 0, zone      DMA      1      0      0      1      2      1      1      0      1      1      3 
Node 0, zone    DMA32      3      3      1      1      1      0      2      3      2      3    745 
Node 0, zone   Normal   1831    712    379    292    304     35     10      7      2     19   1016

こちらの倀ずほが等しくなりたす。

MemFree:         7338756 kB

vmstatでも同じですね。

だいぶ走り曞きな感じですが、ずりあえず今回はこんなずころで 。

参考

Linux メモリ断片化 (外部フラグメンテーション) の概要と解消方法 - Qiita

Linux メモリ管理 徹底入門(カーネル編) - SIerだけど技術やりたいブログ

物理メモリのフラグメント(断片化)の状態を確認する | Redhat Enterprise Linux 4