Slide 1

Slide 1 text

Ί΋Γʔ ྩ࿨࠷৽൛ PHP ϝϞϦ؅ཧज़ PHP ΧϯϑΝϨϯε ؔ੢ 2024

Slide 2

Slide 2 text

Ί΋Γʔ m3m0r7 memory1994 m3m0r7 1994 ೥ 5 ݄ੜ·Εɻෳ਺ͷελʔτΞοϓ ΍্৔اۀͰιϑτ΢ΣΞΤϯδχΞɼΤϯ δχΞϦϯάϚωʔδϟʔɼςοΫϦʔυɼ ࣥߦ໾һ CTO ͷܦݧΛܦΔɻ2023 ೥ 7 ݄ ΑΓגࣜձࣾΤϯϖΠͰιϑτ΢ΣΞΤϯδ χΞͱͯ͠ैࣄɻಉ೥ 10 ݄ΑΓΤϯδχΞ ϦϯάϚωʔδϟʔɻ

Slide 3

Slide 3 text

Slide 4

Slide 4 text

ϝϞϦ͸ͳͥ଍Γͳ͘ͳΔͷ͔ ϝϞϦ֬อͷ͘͠Έ ϝϞϦফඅྔΛ࡟ݮ͢Δʹ͸ ΋͘͡

Slide 5

Slide 5 text

Έͳ͞Μ͸ɼૺ۰ͨ͜͠ͱ͋Γ·͔͢

Slide 6

Slide 6 text

Slide 7

Slide 7 text

ϝϞϦ͕଍Γͳ͍ͳΒ
 ૿΍ͤ͹͍͍͡Όͳ͍

Slide 8

Slide 8 text

ini_set('memory_limit', '-1')

Slide 9

Slide 9 text

…͋·Γڧ͍ݴ༿Λݣ͏ͳΑ
 ऑ͘ݟ͑Δͧ ʢίʔυʣ

Slide 10

Slide 10 text

Slide 11

Slide 11 text

͜͜Ͱɼٙ໰ʹࢥͬͨํ΋ଟ͍Ͱ͠ΐ͏

Slide 12

Slide 12 text

ʮͳͥɼPHP ͸ϝϞϦ͕଍Γͳ͘ͳΔͷ͔ʯ

Slide 13

Slide 13 text

ཧ༝͸୯७໌շͰ͢

Slide 14

Slide 14 text

ͦΕ͸ɼ଍Γͳ͘ͳΔ͘Β͍
 ϝϞϦΛ࢖͍ͬͯΔ͔ΒͰ͢

Slide 15

Slide 15 text

ྫ͑͹͜͏͍ͬͨίʔυ͸
 ݟͨ͜ͱ͋Γ·͔͢ʁ

Slide 16

Slide 16 text

Slide 17

Slide 17 text

͜Ε࣮͸ɼΊͪΌͪ͘ΌϝϞϦ࢖͍·͢

Slide 18

Slide 18 text

࣮ࡍʹࢼͯ͠Έ·͠ΐ͏

Slide 19

Slide 19 text

Slide 20

Slide 20 text

Slide 21

Slide 21 text

ͪͳΈʹɼ࣍ͷίʔυ΋
 ϝϞϦΛΊͬͪΌ࢖͍·͢

Slide 22

Slide 22 text

ࣄલʹ mk fi le 2M template_ fi le.tpl 
 Λ࣮ߦ͓͖ͯ͠·͢

Slide 23

Slide 23 text

Slide 24

Slide 24 text

ʮ͡Ό͊ɼͲ͏ͨ͠Β͍͍ͷ…
 memory_limit ૿΍͢Ҏ֎ʹํ๏͸͋Δͷ…ʁʯ

Slide 25

Slide 25 text

ʮͦ΋ͦ΋ PHP ͰϝϞϦͳΜͯؾʹͯ͠
 ॻ͍ͨ͜ͱͳ͍Αʯ

Slide 26

Slide 26 text

ʮPHP ͕ϝϞϦΛѻ͏࢓૊ΈͳΜͯ஌Βͳ͍Αʯ

Slide 27

Slide 27 text

Allowed memory size of ...
 
 ͳΜͯ΋͏ා͘ͳ͍… ͱࢥͬͯ΋Β͑Δͷ͕
 ຊ೔ͷΰʔϧͰ͢

Slide 28

Slide 28 text

…ͳͬͯ΍Δͥ…໷ͷϝϞϦԦʹ!!

Slide 29

Slide 29 text

ͦͷલʹͳͥϝϞϦ͕଍Γͳ͘ͳΔͷ͔
 ղઆ͍͖ͯ͠·͢

Slide 30

Slide 30 text

※ PHP 8.3 લఏͰղઆ͠·͢

Slide 31

Slide 31 text

ϝϞϦ͸ͳͥ଍Γͳ͘ͳΔͷ͔

Slide 32

Slide 32 text

ͦ΋ͦ΋ϝϞϦͬͯԿʁ - ୺తʹݴͬͯ͠·͑͹ɼσʔλΛҰ࣌తʹه࿥͢Δͱ͜ΖͰ͢
 ʢ※ ࢲͷϋϯυϧωʔϜͱ͸ؔ܎͕͋Γ·ͤΜʂʣ - شൃੑϝϞϦʢ͍ΘΏΔ RAMʣ΍ෆشൃੑϝϞϦͳͲ͋Γ·͢Ͷɻ - ༻్ʹΑͬͯ෼͚ΒΕ·͢ɻ৘ใܥͷֶ෦ग़਎ͷਓ͸ɼߨٛͰ
 ݏʹͳΔ͘Β͍ɼ΍ͬͨΜ͡Όͳ͍͔ͳͱࢥ͍·͢ɻ - ओهԱ૷ஔͱͯ͠࢖ΘΕΔ΋ͷ͸େ൒͕ RAM Ͱ͢ɻ ϝϞϦ͸ͳͥ଍Γͳ͘ͳΔͷ͔

Slide 33

Slide 33 text

ͦ΋ͦ΋ϝϞϦͬͯԿʁ - ྫ͑͹ AWS ͷΠϯελϯεΛબͿͱ͖ʹϝϞϦͷ߲໨ (r5.large ͳͲ)͕͋Δ ͔ͳͱࢥ͍·͕͢ɼͦΕͰ͢ɻͨͩɼϝϞϦͱݺͿͱ͖͸Ծ૝͔෺ཧ͔͋·Γ ؾʹ͍ͯ͠·ͤΜ - ࣮ࡍ͸ଞͷιϑτ΢ΣΞͳͲͰ΋ϝϞϦΛ࢖༻͍ͯ͠ΔͨΊɼࢦఆͨ͠ϝϞ Ϧ͕શͯ࢖͑Δͱ͸ݶΓ·ͤΜ - ͕ͨͬͯ͠ PHP Ͱ ini_set('memory_limit ', '4G') ͳͲͱ҆௚ʹ
 ࢦఆ͢Δͷ͸ϕετϓϥΫςΟεͱ͸ݴ͑·ͤΜɻ ϝϞϦ͸ͳͥ଍Γͳ͘ͳΔͷ͔

Slide 34

Slide 34 text

ϝϞϦ֬อͷ͘͠Έ

Slide 35

Slide 35 text

ىಈ͚ͩͰ΋ 2M ఔ౓࢖༻͍ͯ͠Δཧ༝ - PHP ͸ىಈ࣌ʹ 2M Ҏ্ͷϝϞϦΛͦ΋ͦ΋࢖༻͍ͯ͠·͢ɻ - ྫ͑͹ɼPHP ͷ࣮ߦͰ php -d memory_limit=1K -r "" ͱ͢ΔͱɼPHP ͦͷ ΋ͷ͕࣮ߦͰ͖ͳ͍ࣄ͕Θ͔Γ·͢ɻ ϝϞϦ֬อͷ͘͠Έ php -d memory_limit=1K -r ""

Slide 36

Slide 36 text

ىಈ͚ͩͰ΋ 2M ఔ౓࢖༻͍ͯ͠Δཧ༝ - memory_limit ͷॲཧ͸ https://github.com/php/php-src/blob/php-8.3.2/ main/main.c#L273 ͷ static PHP_INI_MH(OnChangeMemoryLimit) ͰߦΘ Ε͍ͯ·͢ɻ - ࠷ऴతʹ͸ Zend Memory Manager ͕ݺͼग़͞Εͯɼॲཧ͞Ε͍ͯ·͢ɻ - zend_alloc.c ͷ https://github.com/php/php-src/blob/php-8.3.2/Zend/ zend_alloc.c#L2731 Ͱ͋Δ zend_set_memory_limit Ͱ͢ɻ ϝϞϦ֬อͷ͘͠Έ

Slide 37

Slide 37 text

ىಈ͚ͩͰ΋ 2M ఔ౓࢖༻͍ͯ͠Δཧ༝ - ./con fi gure --disable-all ͰϏϧυ࣌ʹશͯͷϞδϡʔϧΛແޮԽʹͯ͠΋ɼ ಛஈϝϞϦ࢖༻ྔ͕ݮΔ͜ͱ͸͋Γ·ͤΜɻ - ϞδϡʔϧΛແޮʹͯ͠΋༗ޮʹͯ͠΋ɼৗʹ 2,097,152 όΠτ (2M)ɹ͕ফඅ ͞Ε͍ͯΔ͜ͱ͕Θ͔Γ·͢ɻ (Ubuntu 20 on Docker ͷ৔߹) - ͦΕ͸ͳͥͰ͠ΐ͏͔ɻ ϝϞϦ֬อͷ͘͠Έ ./con fi gure --disable-all

Slide 38

Slide 38 text

ىಈ͚ͩͰ΋ 2M ఔ౓࢖༻͍ͯ͠Δཧ༝ - Կ΋ॲཧΛ͍ͯ͠ͳ͍ͷʹ 2MB Λ࢖༻͍ͯ͠Δཧ༝͸ zend_alloc_sizes.h ͷ ZEND_MM_CHUNK_SIZE ͱ͍͏ఆ਺͕Ωʔͱͳ͓ͬͯΓɼ͜Ε͕ 2MB ͱͳ͍ͬͯΔ͔ΒͰ͢ - ࢀর: https://github.com/php/php-src/blob/php-8.3.2/Zend/ zend_alloc_sizes.h#L22 - PHP ͸ޮ཰Α͘ॲཧΛ͢ΔͨΊʹɼϝϞϦΛ֬อ͢Δࡍʹ͸͋Δఔ౓όοϑΝ Λ࣋ͬͯ֬อ͢ΔͷͰ͢ɻ ϝϞϦ֬อͷ͘͠Έ

Slide 39

Slide 39 text

ZEND_MM_CHUNK_SIZE ͷఆٛ

Slide 40

Slide 40 text

ىಈ͚ͩͰ΋ 2M ఔ౓࢖༻͍ͯ͠Δཧ༝ - ZEND_MM_CHUNK_SIZE Λ 4MB ʹมߋ͠ɼPHP ΛϏϧυ͠ͳ͓ͯ͠ىಈ ͯ͠ΈΔͱͲ͏Ͱ͠ΐ͏͔ɻ - ͦΕʹ߹Θͤͯ memory_limit ΋ 3MB ʹม͑ͯΈ·͢ɻ ϝϞϦ֬อͷ͘͠Έ 3MB ʹมߋ 4MB ࢖͍ͬͯΔ͜ͱ͕Θ͔Γ·͢

Slide 41

Slide 41 text

ىಈ͚ͩͰ΋ 2M ఔ౓࢖༻͍ͯ͠Δཧ༝ - Ͱ͸ memory_limit Λਖ਼ৗʹىಈͰ͖͏ΔͰ͋Ζ͏ 5MB ʹม͑ͯΈ·͢ ϝϞϦ֬อͷ͘͠Έ 5MB ʹมߋ ਖ਼ৗʹग़ྗ͞Ε͍ͯΔ͜ͱ͕
 Θ͔Γ·͢ ग़ྗ͞ΕΔ͔Λςετ͢ΔͨΊʹ echo ʹॻ͖׵͑ͯ·͢

Slide 42

Slide 42 text

ىಈ͚ͩͰ΋ 2M ఔ౓࢖༻͍ͯ͠Δཧ༝ - ZEND_MM_CHUNK_SIZE ͸ Zend Memory Manager ʢZend MMʣͱݺ͹ ΕΔϝϞϦΛ؅ཧ͢ΔػߏʹΑͬͯޮ཰తʹϝϞϦΛΞϩέʔτʢAllocateɼ ϝϞϦͷྖҬΛ֬อ͢Δ͜ͱʣͤ͞·͢ɻ - ͜ͷػߏΛແޮʹ͠ɼҰൠతʹϝϞϦͷΞϩέʔτͰ༻͍ΒΕΔ malloc Λ࢖ ༻͢Δʹ͸ USE_ZEND_ALLOC=0 ͱ͍͏؀ڥม਺Λࢦఆ࣮ͯ͠ߦ͠·͢ɻ
 ※ PHP ͷϚχϡΞϧʹ͸ຊ൪؀ڥͰͷ࢖༻͸͠ͳ͍Α͏ॻ͔Ε͍ͯ·͢ɻ ϝϞϦ֬อͷ͘͠Έ

Slide 43

Slide 43 text

- PHP ͷϝϞϦ؅ཧԼͷ֎ʹͳΔͷͰɼmemory_get_usage ͳͲͷΑ͏ͳɼϝ ϞϦؔ࿈ͷؔ਺͕ɼ΄ͱΜͲಈ࡞͠ͳ͘ͳΓ·͢ɻ ىಈ͚ͩͰ΋ 2M ఔ౓࢖༻͍ͯ͠Δཧ༝ ϝϞϦ֬อͷ͘͠Έ USE_ZEND_ALLOC=0 Λࢦఆ͢ΔͱΤϥʔ͕ දࣔ͞Ε࣮ͣߦ͞ΕΔ͜ͱ͕Θ͔Γ·͢ ग़ྗ͞ΕΔ͔Λςετ͢ΔͨΊʹ echo ʹॻ͖׵͑ͯ·͢

Slide 44

Slide 44 text

memory_get_usage/memory_get_peak_usage ͷ஋ʹ͍ͭͯ - memory_get_usage/memory_get_peak_usage ͸ true Λୈ 1 Ҿ਺ʹࢦఆ͠ ͨ৔߹ɼZEND_MM_CHUNK_SIZE ϕʔεʹͳΓ·͢ɻ - Zend MM ͕ͲΕ΄Ͳ࣮ࡍʹϝϞϦΛ֬อ͍ͯ͠Δͷ͔Λ஌Γ͍ͨ৔߹ʹ༗ ༻Ͱ͢ɻ - ͳ͓ɼPHP ͷϓϩηε͕࢖͍ͬͯΔϝϞϦফඅྔͰ͸͋Γ·ͤΜͷͰ஫ҙ ͕ඞཁͰ͢ɻ ϝϞϦ֬อͷ͘͠Έ

Slide 45

Slide 45 text

memory_get_usage/memory_get_peak_usage ͷ஋ʹ͍ͭͯ - ͦͷதͷ௨ৗͷϝϞϦফඅྔΛಘ͍ͨ৔߹͸ ୈ 1 Ҿ਺ʹ͸ಛஈࢦఆ͠ͳ͍΄ ͏͕ྑ͍Ͱ͢ɻ - ୈҰҾ਺Λࢦఆ͠ͳ͍৔߹ͷϢʔεέʔεͱͯ͠͸ɼྫ͑͹ಛఆͷॲཧͷൣ ғͰͲΕ͘Β͍ϝϞϦ͕ফඅ͞Ε͍ͯΔͷ͔Λ஌Γ͍ͨਓ޲͚ʹ༗༻Ͱ͢ɻ - PHP ͷϓϩηεຊମͷϝϞϦ࢖༻ྔͰ͸ͳ͍ͨΊ memory_limit ಺ʹϝϞ Ϧͷ࢖༻ྔΛऩΊΔͨΊͷϘτϧωοΫΛ୳͢༻్͘Β͍͔͠ࢲ͸ࢥ͍ු͔ ͹ͳ͍Ͱ͕͢…ɻଞʹ͜͏͍͏༻్͕͋ΔΑͳͲ͋Ε͹ڭ͍͑ͯͩ͘͞ʂ ϝϞϦ֬อͷ͘͠Έ

Slide 46

Slide 46 text

memory_get_usage/memory_get_peak_usage ͷ஋ʹ͍ͭͯ - ୈ 1 Ҿ਺ʹ true Λ౉ͨ͠৔߹ ϝϞϦ֬อͷ͘͠Έ ஋ʹมԽͳ͠ ஋ʹมԽͳ͠

Slide 47

Slide 47 text

memory_get_usage/memory_get_peak_usage ͷ஋ʹ͍ͭͯ - ୈ 1 Ҿ਺ʹ true Λ౉͞ͳ͔ͬͨ৔߹ ϝϞϦ֬อͷ͘͠Έ ஋ʹมԽ͋Γ
 ʢͨͩ͠಺෦ͰͷϝϞϦফඅྔ͸มԽͳ͠ʣ ஋ʹมԽ͋Γ
 ʢͨͩ͠಺෦ͰͷϝϞϦফඅྔ͸มԽͳ͠ʣ

Slide 48

Slide 48 text

memory_get_usage/memory_get_peak_usage ͷ஋ʹ͍ͭͯ - ͜ΕΒͷ஋͸ Zend Memory Manager ͕ϕʔεͱͳ͍ͬͯΔͨΊ
 USE_ZEND_ALLOC=0 ͱͨ͠৔߹͸ৗʹ 0 ͕ฦΓ·͢ɻ - ·ͨɼ͜Ε͸ PHP ͕ϓϩηεͱͯ͠࢖༻͍ͯ͠ΔϝϞϦফඅྔͰ͸ͳ͍ ʢZend Memory Manager ্Ͱ͋ΔͨΊʣͨΊϓϩηεͦͷ΋ͷ͕࢖༻ͯ͠ ͍ΔϝϞϦফඅྔΛ஌Γ͍ͨ৔߹͸ɼҟͳΔखஈ͕ඞཁͰ͢ɻ - ஫) USE_ZEND_ALLOC=0 ͸ɼϝϞϦϦʔΫݕग़࣌Ҏ֎ʹ࢖͏΂͖΋ͷͰ͸ͳ͍ͱ PHP ϚχϡΞϧʹهࡌ͞Ε͍ͯ·͢ɻ
 ࢀর: http://php.adamharvey.name/manual/ja/internals2.memory.management.php ϝϞϦ֬อͷ͘͠Έ

Slide 49

Slide 49 text

memory_get_usage/memory_get_peak_usage ͷ஋ʹ͍ͭͯ - PHP ͷϓϩηεͦͷ΋ͷ͕ར༻͍ͯ͠ΔϝϞϦ࢖༻ྔΛٻΊ͍ͨ৔߹͸ҎԼ ͷΑ͏ʹ͢Δ͜ͱͰऔಘͰ͖·͢ɻ - VSS (Virtual Set Size, ϓϩηε͕֬อ͍ͯ͠ΔԾ૝ϝϞϦͷαΠζ) - system("ps u -p" . getmypid() . " | grep php | awk '{print $5}'"); - RSS (Resident Set Size, ϓϩηε͕༧Ί֬อ͍ͯ͠Δ෺ཧϝϞϦͷαΠζ) - system("ps u -p" . getmypid() . " | grep php | awk '{print $6}'"); ϝϞϦ֬อͷ͘͠Έ system("ps u -p" . getmypid() . " | grep php | awk '{print $5}'"); system("ps u -p" . getmypid() . " | grep php | awk '{print $6}'");

Slide 50

Slide 50 text

༨ஊ: POST ͷαΠζʹ͍ͭͯ - ଞʹ΋ૹΒΕͯ͘Δ POST ͷαΠζΛܾఆ͢Δ post_max_size ͳͲ͕͋Γ· ͢ɻ - ͜Ε͸Ұ࣌ϑΝΠϧͱͯ͠࡞੒͞ΕΔͨΊɼmemory_limit > post_max_size Ͱ͋Δඞཁ͸͋Γ·ͤΜɻ - php -d memory_limit=4M -d post_max_size=16M -S 0.0.0.0:8000 ͰϏϧ τΠϯαʔόʔΛىಈ͠ɼ࣮ࡍʹ 4MB ΑΓେ͖͍ϑΝΠϧΛૹ৴ͯ͠΋ɼ ໰୊ͳ͍͜ͱ͕֬ೝͰ͖·͢ɻ ϝϞϦ֬อͷ͘͠Έ

Slide 51

Slide 51 text

༨ஊ: POST ͷαΠζʹ͍ͭͯ - ͨͩ͠ɼSAPI_POST_BLOCK_SIZE (σϑΥϧτ 16,384 bytes) ෼ͷϝϞϦ͸ ʢZend Memory Manager ͷ֎Ͱʣ࢖༻͞Ε·͢ɻ - ͜ͷ஋ʹ͍ͭͯ͸ memory_get_usage ͳͲͰ͸औಘͰ͖·ͤΜɻPHP ͷ಺ ෦ґଘͷ࣮૷ʹͳΓ·͢ɻ - memory_get_usage ͸ɼҰ෦ྫ֎Λআ͖·͕͢ɼجຊతʹ͸Ϣʔβʔϥϯυ ͷίʔυͷϝϞϦ࢖༻ྔ͕ੵ·Ε͍ͯ͘͜ͱʹ஫ҙ͢Δඞཁ͕͋ΔͷͰ͢ɻ ϝϞϦ֬อͷ͘͠Έ

Slide 52

Slide 52 text

༨ஊ: POST ͷαΠζʹ͍ͭͯ - ࿩Λ໭͢ͱ post_max_size ͸αʔόʔ͕Ұ࣌ϑΝΠϧΛ࡞੒Ͱ͖Δ༰ྔʹ Αܾͬͯఆ͢΂͖Ͱ͋Δͱݴ͑·͢ɻ - ొஃ಺༰͔ΒҳΕΔͷͰৄࡉ͸ׂѪ͠·͕͢ɼҰ࣌ϑΝΠϧɼΦʔϓϯՄೳͳ ϑΝΠϧ਺ͳͲΛߟྀͨ͠ͱ͖ʹɼΧʔωϧύϥϝʔλͷௐ੔͕ඞཁʹͳΔՄ ೳੑ΋͋Γ͑·͢ɻ ϝϞϦ֬อͷ͘͠Έ

Slide 53

Slide 53 text

༨ஊ: POST ͷαΠζʹ͍ͭͯ - ͜Ε͸ post_max_size >= upload_max_ fi lesize Ͱ͋Δඞཁ͕͋Γ·͢ɻ post_max_size ͕શମͷ POST ͷαΠζΛࢦఆ͢Δͷʹରͯ͠ɼ upload_max_ fi lesize ͸ POST ͷதͷૹ৴͞Εͨ multipart Λࢀর͢ΔͨΊͰ ͢ɻ - ͳ͓ɼ͜Ε͸ 1 ϑΝΠϧ͋ͨΓͰ͸ͳ͘ɼશͯͷϑΝΠϧͷαΠζͷ߹ܭ Ͱ͢ ϝϞϦ֬อͷ͘͠Έ

Slide 54

Slide 54 text

PHP ͷϝϞϦͱม਺ͷؔ܎ - ม਺ʹೖΔ஋͸ɼͦͷ··૝ఆͨ͠ ϝϞϦ࢖༻ྔʹͳΔΘ͚Ͱ͸͋Γ· ͤΜɻ - ྫ͑͹ӈهͷίʔυ͸ 0 Λظ଴͠· ͕͢ɼ࣮ࡍ͸ -256 Ͱग़ྗ͞Ε·͢ɻ ϝϞϦ֬อͷ͘͠Έ

Slide 55

Slide 55 text

PHP ͷϝϞϦͱม਺ͷؔ܎ - $tmp ʹจࣈྻΛ୅ೖ͍ͯͯ͠΋ɼͦ ͷ৔Ͱ͸ Zend MM ্ͰϝϞϦফඅ ྔ͸Ճࢉ͞Ε·ͤΜɻ - ·ͨɼ$tmp2 ΋ PHP ͸ CoW (Copy on Write) Ͱ͋ΔͨΊɼಉ༷ʹ ͜ͷ࣌఺Ͱ΋ϝϞϦͷফඅྔ͸Ճࢉ ͞Ε·ͤΜɻ ϝϞϦ֬อͷ͘͠Έ

Slide 56

Slide 56 text

PHP ͷϝϞϦͱม਺ͷؔ܎ - ͔͠͠ɼӈهͷΑ͏ʹίʔυΛॻ͖׵͑Δ ͱɼ4,210,712 ͷϝϞϦফඅྔ͕͋Δ͜ͱ͕ Θ͔Γ·͢ - ͭ·Γɼ࢖ΘΕ͍ͯͳ͍ม਺Ͱ΋ؔ਺ݺͼग़ ͠ͷ৔߹͸ϝϞϦ͸ফඅ͞ΕΔͱ͍͏͜ͱͰ ͢ɻ - Ώ͑ʹɼ࢖ͬͯͳ͍ม਺͕͋Ε͹ফ͢ͱ͍͏ ͜ͱΛ৺͕͚·͠ΐ͏ɻ ϝϞϦ֬อͷ͘͠Έ

Slide 57

Slide 57 text

PHP ͷϝϞϦͱม਺ͷؔ܎ - ϓϦϛςΟϒͳ஋Λࢦఆ͢Δ৔߹ͱɼؔ਺ݺͼग़͕͋͠Δ৔߹Ͱ͸·ͬͨ͘ ΋ͬͯҧ͏ͱ͍͏͜ͱ͕Θ͔Γ·͢ɻ - ྫ͑͹͜ΕΛ int ܕ΍ array ܕͷ஋ʹஔ͖׵͑ͨΒ 0 ͱग़ྗ͞ΕΔ͜ͱ͕Θ͔ Γ·͢ɻͪͳΈʹ memory_get_peak_usage Ͱ΋ಉ༷Ͱ͢ɻ - ͭ·Γɼ͋ͨΓ·͑Ͱ͸͋Γ·͕͢ɼؔ਺ݺͼग़͠͸ۃྗ߇͑ͯɼϓϦϛςΟ ϒܕͰͳΔ΂͘ॲཧ͢Δ΄͏͕ϝϞϦͱ͍͏؍఺Ͱ͸ޮ཰తͩͱݴ͑·͢ɻ ϝϞϦ֬อͷ͘͠Έ

Slide 58

Slide 58 text

PHP ͷϝϞϦͱม਺ͷؔ܎ - ͱ͸͍͑ɼϓϦϛςΟϒܕͷϝϞϦফඅྔ ͕θϩ͔ͱ͍͏ͱͦ͏Ͱ͸ͳ͍ͷͰ͢ɻ - ઌ΄Ͳͷྫͷؔ਺ͷݺͼग़͠Λ͍ͯ͠Δม ਺ఆٛͷՕॴΛ഑ྻʹ͢ΔͱͲ͏ͳΔͰ ͠ΐ͏͔ɻ - ͜ΕͰ࣮ߦͯ͠Έ·͠ΐ͏ɻ ϝϞϦ֬อͷ͘͠Έ

Slide 59

Slide 59 text

PHP ͷϝϞϦͱม਺ͷؔ܎ - ϝϞϦফඅྔ͸ 4,210,928 bytes ͱͳΓɼ216 bytes ૿͑Δ͜ͱ͕Θ͔Γ· ͢ɻ - 2 ࣍ݩ഑ྻɼ3 ࣍ݩ഑ྻͱ૿΍͍ͯ͘͠ͱɼϝϞϦফඅྔ͕૿͍͖͑ͯ·͢ - ഑ྻʹ͢Δ͚ͩͰ΋࢖༻ྔ͕มΘΔͱ͍͏͜ͱ͕Θ͔Γ·͢ɻ - จࣈྻܕ΍഑ྻܕͳͲ͕Ͳͷ͘Β͍ϝϞϦΛ࢖͏͔ʹ͍ͭͯ͸
 zend_types.h ʹهࡌ͞Ε͍ͯ·͢ ϝϞϦ֬อͷ͘͠Έ

Slide 60

Slide 60 text

PHP ͷϝϞϦͱม਺ͷؔ܎ จࣈྻܕ΍഑ྻܕͳͲ͕Ͳͷ͘Β͍ϝϞϦ Λ࢖͏͔ʹ͍ͭͯ͸ zend_types.h ʹهࡌ ͞Ε͍ͯ·͢ɻͳ͓ɼ਺஋ܕͷ৔߹͸ zend_long.h Ͱఆٛ͞Ε͍ͯ·͢ɻ ϝϞϦ֬อͷ͘͠Έ จࣈྻͷ৔߹ ഑ྻͷ৔߹

Slide 61

Slide 61 text

PHP ͷϝϞϦͱม਺ͷؔ܎ ϝϞϦ֬อͷ͘͠Έ - ·ͨɼint ܕ ΍ string ܕͩͬͨΒৗʹ 0 ͔ͱ ͍͏ͱɼͦ͏͍͏Θ͚Ͱ͸͋Γ·ͤΜɻ - ӈਤͷΑ͏ʹจࣈྻΛ 3MB ॻ͖ग़ͨ͠
 ϑΝΠϧΛ࡞੒͠ɼ࣮ࡍʹ࣮ߦ͢Δͱ
 ҎԼͷΑ͏ʹΤϥʔ͕ग़·͢

Slide 62

Slide 62 text

GC ͱ ऑࢀরʢWeakrefʣ ($ (BSCBHF$PMMFDUJPO ΨϕʔδίϨΫγϣϯ ͸ɼҰఆͷ৚݅Λຬͨͨ͠ ৔߹ʹɼม਺΍஋ͷϝϞϦղ์Λߦ͏΋ͷͰ͢ 1)1ʹ͸SFGDPVOUʢϦϑΝϨϯεΧ΢ϯτʣͱݺ͹ΕΔɼ͍Θ͹ม਺ͷݺͼ ग़͠ճ਺Λه࿥͢Δػೳ͕͋Γɼ͜ͷ஋Λ༻͍ͯɼ($ͷର৅Ͱ͋Δ͔Ͳ͏͔ Λ൑ఆ͍ͯ͠·͢ ࢀরIUUQTXXXQIQOFUNBOVBMKBGFBUVSFTHDSFGDPVOUJOH CBTJDTQIQ ϝϞϦ֬อͷ͘͠Έ

Slide 63

Slide 63 text

GC ͱ ऑࢀরʢWeakrefʣ ಛʹ໰୊ʹͳΓ΍͍͢ͷ͸॥؀ࢀরͰ͢ɻ॥؀ࢀরͱ͸ɼ"ͱ#ͷΦϒδΣΫ τ΍ม਺͕͋ͬͨͱ͖ʹɼ"͕#Λɼ#͕"Λࢀরʢ˺ґଘʣ͢Δঢ়ଶΛࢦ ͠ɼϝϞϦ͕֬อ͞Εͨ··ʹͳΓɼ࠷ऴతʹϝϞϦϦʔΫͱͳͬͯ͠·͏΋ ͷͰ͢ɻ ॥؀ࢀর͕ൃੜ͢Δͱ($͕૸Δ·Ͱ͸ɼϝϞϦ͕ফඅ͞Εͯ͠·͍·͢ɻ ͕ͨͬͯ͠ɼͦ΋ͦ΋॥؀ࢀরʹͳΒͳ͍Α͏ͳΞʔΩςΫνϟΛ 
 ਪ঑͠·͢ ϝϞϦ֬อͷ͘͠Έ

Slide 64

Slide 64 text

॥؀ࢀরΛൃੜͤ͞Δίʔυͷྫ

Slide 65

Slide 65 text

GC ͱ ऑࢀরʢWeakrefʣ ॥؀ࢀরͰɼ($͕૸Βͳ͔ͬͨ৔߹ɼҎԼͷΑ͏ʹ"MMPXFENFNPSZTJ[F PG͕ग़ྗ͞Ε·͢ɻ ϝϞϦ֬อͷ͘͠Έ

Slide 66

Slide 66 text

GC ΛखಈͰൃಈͤ͞Δྫ echo $cycle2; ͷਅԼʹ
 
 gc_collect_cycles();
 
 Λ௥ه

Slide 67

Slide 67 text

GC ͱ ऑࢀরʢWeakrefʣ ҰํͰखಈͰHD@DPMMFDU@DZDMFTΛ࣮ ߦʢFDIPDZDMFਅԼʹ௥Ճʣͨ͠ ৔߹ɼӈهͷΑ͏ʹ࠷ޙ·Ͱɼϓϩά ϥϜ͕࣮ߦ͞ΕΔ͜ͱ͕Θ͔Γ·͢ɻ ϝϞϦ֬อͷ͘͠Έ

Slide 68

Slide 68 text

GC ͱ ऑࢀরʢWeakrefʣ ॥؀ࢀরʹΑͬͯɼSFGDPVOU͕૿͍͑ͯͨ͘Ίɼ($ΛखಈͰൃಈ͠ͳ͍ͱϝ ϞϦղ์͕ߦΘΕͳ͍͜ͱ͕Θ͔Γ·ͨ͠ɻ ͱ͸͍͑ɼ1)1্Ͱ೚ҙͷλΠϛϯάͰ($Λ૸ΒͤΔͷ͸ਓྨʹ͸·ͩૣ ͍ͨΊɼऑࢀরʢ8FBL3FGʣΛ࢖༻͢ΔͳͲͷ޻෉͕ඞཁͰ͢ɻ ઌ΄ͲͷίʔυྫΛऑࢀর͕࢖͑ΔΑ͏ʹॻ͖׵͑ɼղઆ͍͖ͯ͠·͢ɻ ϝϞϦ֬อͷ͘͠Έ

Slide 69

Slide 69 text

CycleTest Λऑࢀরʹͤ͞Δ ऑࢀরͷΦϒδΣΫτΛ CycleTest ʹ౉͢ ड͚ೖΕΔܕΛม͑Δ ड͚ೖΕΔܕΛม͑Δ

Slide 70

Slide 70 text

GC ͱ ऑࢀরʢWeakrefʣ ऑࢀরʹॻ͖׵͑ͨ͜ͱͰɼSFGDPVOU͕͍ ͍ײ͡ʹௐઅ͞Ε͏·͘($͕૸ΔΑ͏ʹ ͳΓ·ͨ͠ɻ݁Ռͱͯ͠࠷ޙ·Ͱϓϩάϥ Ϝ͕࣮ߦͰ͖ΔΑ͏ʹͳ͍ͬͯ·͢ɻ ·ͨɼಠཱͨ͠ΦϒδΣΫτΛ࢖͏͜ͱͰ ճආ͢Δ͜ͱ΋Ͱ͖·͢ɻ͜ͷΑ͏ͳέʔ εͷ৔߹DMPOFΛ༻͍Δ͜ͱ͕༗༻Ͱ͢ɻ ϝϞϦ֬อͷ͘͠Έ

Slide 71

Slide 71 text

clone Λ࢖͏ͱ॥؀ࢀরͰ͸ͳ͘ͳΔͨΊ
 memory_limit ͕ 2M Ͱ΋࠷ޙ·Ͱग़ྗͰ͖Δ

Slide 72

Slide 72 text

ϝϞϦফඅྔΛ࡟ݮ͢Δʹ͸

Slide 73

Slide 73 text

memory_limit ͷϕετϓϥΫςΟε - 2*N ʢN ͸ࣗવ਺ʣMB Λߟྀͯ͠ memory_limit ઃఆΛ͠·͠ΐ͏ɻ - ͦ΋ͦ΋ memory_limit ͷԼݶ͸ 2MB (ZEND_MM_CHUNK_SIZE ʹΑΔ)ͳ ͷͰɼϝϞϦফඅྔ 2MB Ҏ಺Ͱॲཧ͕ॻ͚Δͱϕετ - ͜Ε͸ memory_limit ͷσϑΥϧτ 128MB Ͱ͋ͬͯ΋ɼॳճͷղ์͞ΕΔ ஋͕ 2MB ͱ͍͏͜ͱͰ͢ɻ ϝϞϦফඅྔΛ࡟ݮ͢Δʹ͸

Slide 74

Slide 74 text

memory_limit ͷϕετϓϥΫςΟε - 2MB+1B ͔͠࢖ͬͯͳ͍Α͏ʹݟ͑ͯ΋ɼཪͰ͸݁ہ 2MB (ZEND_MM_CHUNK_SIZE) * 2 = 4MB ϝϞϦΛফඅͯ͠ΔΘ͚Ͱ͢ɻ - memory_get_usage(false) ͳͲͷ஋ΛνϚνϚվળͯ͠΋ɼ݁ہϝϞϦ͸ ফඅ͞Ε͍ͯΔͷͰҙຯ͕͋Γ·ͤΜɻ࣌ؒΛ࢖͏͚ͩແବͰ͢ɻ - ͜ͷΑ͏ͳέʔε͸ 4MB ϑϧʹ࢖ͬͨ΄͏͕ޮ཰తͰ͢ɻ - ͭ·ΓɼPHP ʹ͓͚Δ memory_limit ͸ 2MB ͷഒ਺Λઃఆ͠ɼͦͷ஋ ͷதͰ࢖ͬͯ͋͛Δͷ͕࠷΋ޮ཰తͰޮՌతͰ͢ɻ ϝϞϦফඅྔΛ࡟ݮ͢Δʹ͸

Slide 75

Slide 75 text

memory_limit ͷϕετϓϥΫςΟε - ྫ͑͹ AWS Λ࢖༻͍ͯ͠ΔํͰ c5.large Λબఆ͍ͯ͠Δ৔߹͸ϝϞϦ͸ 4GB ͱͳΔͷͰɼphp-fpm ͳͲͷଞϓϩηεͷϝϞϦ࢖༻ྔ΋Ճຯ্ͨ͠Ͱ - 2M * N (1 <= N < (4G/2), N ͸ࣗવ਺) ͳͲͱݟੵ΋Δͱྑ͍Ͱ͠ΐ͏ɻ - ࡢࠓͷΞϓϦέʔγϣϯ͸ΨϕʔδίϨΫγϣϯʹ೚͖ͤΓͰɼϝϞϦϦʔΫ Λසൟʹى͍ͯͨ͜͠Γ΋͠·͢ɻΏ͑ʹɼطଘͷΞϓϦέʔγϣϯͷঢ়ଶ΋ ΋ͪΖΜՃຯ͢Δ͜ͱ͕ॏཁͰ͢ɻ ϝϞϦফඅྔΛ࡟ݮ͢Δʹ͸

Slide 76

Slide 76 text

memory_limit ΑΓ΋େ͖ͳ஋Λ࢖͍͍ͨ - εϫοϓ΍όοϑΝΛ͏·͘ѻ͏͜ͱͰɼmemory_limit ΑΓ΋େ͖ͳ஋Λ࢖ ͏͜ͱ͕ՄೳͰ͢ɻ - ྫ͑͹ memory_limit Λ 2M ͱࢦఆ͍ͯ͠Δ৔߹͸Ծఆ͠·͢ɻ͜ͷέʔεͷ ͱ͖ɼ 4M ͷϑΝΠϧͷத਎Λग़ྗ͠Α͏ͱ
 `echo fi le_get_contents('test_heavy.log')` ͷΑ͏ʹ۪௚ʹॻ͘ͱϝϞϦ͕ෆ ଍ͯ͠͠·͍·͢ɻ - ࣍ͷϖʔδͷΑ͏ʹ෼ׂͯ͋͛͠Δ͜ͱͰϝϞϦফඅྔΛ཈͑Δ͜ͱ͕ՄೳͰ ͢ɻ ϝϞϦফඅྔΛ࡟ݮ͢Δʹ͸ echo fi le_get_contents('test_heavy.log')

Slide 77

Slide 77 text

ͪͳΈʹɼ͋ͨΓ·͑Ͱ͕͢ fread ͷୈೋҾ਺Λ
 2M ʹมߋ͢ΔͱϝϞϦෆ଍ʹͳΓ·͢

Slide 78

Slide 78 text

memory_limit ΑΓ΋େ͖ͳ஋Λ࢖͍͍ͨ - PHP Λհͯ͠ը૾Λ base64 ͱͯ͠ग़ྗ͍ͨ͠έʔεͳͲ΋͋Δ͔ͱࢥ͍· ͢ɻ - ϑΝΠϧαΠζ͕খ͍͞ɼ΋͘͠͸ఆ·͍ͬͯΔͷͳΒ͹ɼ·ͩڐ༰Ͱ͖·͢ ͕ɼϑΝΠϧαΠζ͕େ͖͍৔߹͸Ұ޻෉͕ඞཁͰ͢ɻ - ಛʹ PHP ͕ϏϧτΠϯͰఏڙ͍ͯ͠Δbase64_encode/base64_decode ͸શ ͯͷจࣈྻΛ౉͢ඞཁ͕͋Γ·͢ɻ ϝϞϦফඅྔΛ࡟ݮ͢Δʹ͸

Slide 79

Slide 79 text

memory_limit ΑΓ΋େ͖ͳ஋Λ࢖͍͍ͨ - 57 * 143 bytes ͝ͱʹ෼ׂͨ͠จࣈྻΛ base64_encode ͢Δ͜ͱ͕࣮͸Մೳ Ͱ͢ɻ͜Ε͸ base64 ΤϯίʔσΟϯάͷ࢓૊Έʹଇͬͨͪΐͬͱٕͨ͠Ͱ ͢ɻ - ࢀর: https://www.php.net/manual/ja/function.base64- encode.php#111942 - ຊ౰͸͜ΜͳখखઌͷٕΛ࢖͏ͷͰ͸ͳ͘ɼCDN ʹஔ͘ͳͲΞʔΩςΫνϟ ͱͯ͋͠Δ΂͖࢟͸໨ࢦ͍͖͍ͯͨ͠΋ͷͰ͢ɻ ϝϞϦফඅྔΛ࡟ݮ͢Δʹ͸

Slide 80

Slide 80 text

෼ׂͰग़ྗ͢Δ͜ͱͰɼmemory_limit ͕ 
 2M Ͱ΋ਖ਼͘͠දࣔͰ͖·͢

Slide 81

Slide 81 text

ob_* ؔ਺ͷέʔε ଞʹ΋PC@TUBSUPC@HFU@DMFBOΛ࢖͏ͳͲ ͕͋Γ·͢Ͷɻ࣮͸PC@TUBSUͷୈҾ਺ʹ όοϑΝΛड͚औΓɼͦͷ஋ΛՃ޻͢Δ͜ͱ ͕Ͱ͖ΔίʔϧόοΫΛ౉͢͜ͱ͕Ͱ͖· ͢ɻ ͜ͷίʔϧόοΫΛ׆༻͠ɼࢦఆͨ͠νϟϯ ΫαΠζͷ஋Λग़ྗ͢ΔͳͲͯ͠ผϑΝΠϧ ʹॻ͖ࠐΉͳͲͰϝϞϦফඅྔΛ཈͑ΒΕ· ͢ɻ ϝϞϦফඅྔΛ࡟ݮ͢Δʹ͸

Slide 82

Slide 82 text

͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠