Jak wyłączyć używanie systemu wymiany w systemie Mac OS X, gdy wciąż istnieje „nieaktywna” pamięć?


61

Powszechnym zjawiskiem w moim codziennym użytkowaniu (i kilku innych, według różnych postów w Internecie) OS X, system wydaje się zwalniać, gdy nie ma już dostępnej „wolnej” pamięci. Podobno wynika to z zamiany, ponieważ widoczna jest duża aktywność dysku i vm_stat zgłasza wiele stron. (Popraw mnie źle)

Jednak ilość „nieaktywnego” pamięci RAM wynosi zazwyczaj około 12,5% -25% całej dostępnej pamięci (^ 1.), Kiedy zamiana rozpoczyna się / występuje / kończy.

Według http://support.apple.com/kb/ht1342 :

Nieaktywna pamięć

Ta informacja w pamięci nie jest aktywnie wykorzystywana, ale została ostatnio wykorzystana.

Na przykład, jeśli korzystasz z Mail, a następnie go opuszczasz, pamięć RAM, z której korzystał Mail, jest oznaczana jako pamięć nieaktywna. Ta nieaktywna pamięć jest dostępna do użycia przez inną aplikację, podobnie jak Wolna pamięć. Jeśli jednak otworzysz Maila, zanim jego nieaktywna pamięć zostanie użyta przez inną aplikację, Mail otworzy się szybciej, ponieważ jego nieaktywna pamięć jest konwertowana na pamięć aktywną, zamiast ładować pocztę z wolniejszego dysku twardego.

I zgodnie z http://developer.apple.com/library/mac/#documentation/Performance/Conceptual/ManagingMemory/Articles/AboutMemory.html :

Nieaktywna lista zawiera strony, które obecnie znajdują się w pamięci fizycznej, ale nie były ostatnio dostępne. Strony te zawierają prawidłowe dane, ale mogą zostać w dowolnym momencie zwolnione z pamięci .

Tak więc w zasadzie: kiedy program zakończy pracę, jego pamięć zostaje oznaczona jako Nieaktywna i powinna być dostępna w dowolnym momencie. Mimo to OS X będzie wolał zacząć zamieniać pamięć na plik wymiany zamiast po prostu zajmować tę pamięć, ilekroć ilość wolnej pamięci spadnie.

Dlaczego? Jaka jest przewaga tego zachowania nad, powiedzmy, natychmiastowym zwalnianiem nieaktywnej pamięci i nawet nie dotykaniem pliku wymiany? Niektóre źródła (^ 2.) Wskazują, że OS X wyświetla stronę „Nieaktywną” w celu zamiany pamięci przed jej zwolnieniem, ale nie ma to teraz sensu, czy pamięć może zostać w dowolnym momencie zwolniona z pamięci ? Zamiana jest droga, wydanie jest tanie, prawda?

Czy to zachowanie można zmienić za pomocą preferencji lub znanego hakowania? (Najlepiej taki, który nie obejmuje całkowitego wyłączenia swap / dynamic_pager i ponownego uruchomienia ...)

Doceniam polecenie czyszczenia , a także koncepcję Naprawianie uprawnień do dysku w celu wymuszenia wolnej pamięci, ale są to sposoby na boleśnie wymuszenie większej ilości Wolnej pamięci niż faktyczne naprawienie logiki decyzji zamiany / wydania ...

Btw podobne pytanie zostało zadane tutaj: http://forums.macnn.com/90/mac-os-x/434650/why-does-os-x-swap-when/ i tutaj: http: //hintsforums.macworld .com / showthread.php? t = 87688, ale mimo że operatorzy ponownie zadali podstawowe pytanie, żadna z odpowiedzi nie zawiera odpowiedzi na to pytanie ...

^ 1. AKTUALIZACJA 17-mar-2012 Od kiedy po raz pierwszy opublikowałem to pytanie, przeszedłem z 4 GB do 8 GB zainstalowanego pamięci RAM, a problem pozostaje. Ilość „nieaktywnego” pamięci RAM wynosiła wcześniej 0,5 gb-1,0 gb i obecnie wynosi zwykle około 1,0-2,0 GB, kiedy zamiana zaczyna się / występuje / kończy, tzn. Wydaje się, że około 12,5% -25% pamięci RAM jest zachowane jako nieaktywne przez osx logika jądra.

^ 2. Na przykład https://apple.stackexchange.com/questions/4288/what-does-it-mean-if-i-have-lots-of-inactive-memory-at-the-end-of-a-work- dzień :

Po wykorzystaniu całej pamięci (wolna pamięć wynosi 0), system operacyjny wypisze nieaktywną pamięć do pliku wymiany, aby zrobić więcej miejsca w aktywnej pamięci.

AKTUALIZACJA 17 marca 2012 r

Oto podsumowanie metod, które do tej pory zostały zasugerowane:

Czystka komenda

„Służy do przybliżania początkowych warunków rozruchu przy użyciu bufora bufora zimnego dysku do analizy wydajności. Nie wpływa na anonimową pamięć przydzieloną przez malloc, vm_allocate itp.”.

Jest to przydatne, aby zapobiec wymianie pamięci podręcznej dysku przez osx (co jest absurdalne, że osx faktycznie tak robi), ale z wadą zwolnienia pamięci podręcznej dysku, co oznacza, że ​​jeśli pamięć podręczna dysku nie miała być po wymianie, po prostu skończyłoby się to buforowaniem zimnego bufora dysku, prawdopodobnie wpływając negatywnie na wydajność.

Aplikacja FreeMemory i / lub Naprawianie uprawnień do dysku w celu wymuszenia wolnej pamięci

Nie pomaga zwolnić pamięci, tylko przenosi niektóre gigabajty zawartości pamięci z pamięci RAM na dysk HD. W końcu powoduje to wiele zamian, gdy próbuję korzystać z aplikacji, które były otwarte podczas zwalniania pamięci, ponieważ wiele jego vm jest teraz w trakcie wymiany.

Przyspieszenie alokacji swapów za pomocą dynamicpagerwrapper

Wydaje się, że dobrym pomysłem jest przyspieszenie użycia wymiany, ale nie rozwiązuje problemu zamiany osx w pierwszej kolejności, gdy pamięć jest nadal nieaktywna.

Wyłączanie zamiany poprzez wyłączenie dynamicpager i ponowne uruchomienie

Zmusi to osx do niestosowania wymiany na cenę zawieszenia systemu, gdy używana jest cała pamięć. Nie jest realną alternatywą ...

Wyłączanie wymiany za pomocą zhakowanego dynamicznego pagera

Podobnie do powyższego wyłączenia dynamicznego pagera, niektóre fragmenty komentarzy do postu na blogu wskazują, że nie jest to realne rozwiązanie: „Pamięć nieaktywna jest jak zwykle wysoka”. „gdy w systemie kończy się pamięć, cały system operacyjny zawiesza się ...”, „jeśli zużyjesz całą ilość pamięci komputera Mac, komputer prawdopodobnie się zawiesi”

Podsumowując, wciąż nie jestem świadomy sposobu, aby wyłączyć system Mac OS X z zamiany, gdy wciąż jest „nieaktywna” pamięć. Jeśli nie jest to możliwe, może przynajmniej istnieje jakieś wytłumaczenie, dlaczego osx woli wymieniać pamięć, która może zostać zwolniona z pamięci w dowolnym momencie ?


1
Mam ten problem, ilustrowany numerami Monitora aktywności: bassistance.de/i/f2322d.png Prawie żadna wolna pamięć, ale mnóstwo nieaktywnej pamięci. Zamiast tego odzyskać, OSX woli zacząć intensywnie wymieniać, jak widać po 40 GB stron.
Jörn Zaefferer

Mam dużo wolnej pamięci i wciąż jest używanych wiele GB wymiany. 16 GB rMBP.
Steven Lu,

1
najwyraźniej niektóre osoby zgłosiły korzyści płynące z uruchomienia „purge” apple.stackexchange.com/questions/67031/… nieujemne
rogerdpack

Odpowiedzi:


19

Z definicji nieaktywna pamięć jest pamięcią gotową do stronicowania, a stronicowanie może wiązać się z zapisaniem jej do zamiany. Nie jest to żaden problem ani problem, który należy zoptymalizować; w rzeczywistości OS X działa zgodnie z przeznaczeniem .

Niestety twórcy pomocy technicznej nie są programistami jądra, a cytat z artykułu pomocy Apple Knowledge Base jest po prostu błędny, gdy twierdzi, że pamięć nieaktywna jest pamięcią nieużywaną przez programy. Po wyjściu z programu cała jego rezydentna pamięć staje się wolna; nie zatrzymuje się w trybie nieaktywnym. Jednak drugi link do strony dla programistów opisujący działanie zarządzania pamięcią jest dobrym zasobem, jeśli zostanie w pełni przeczytany.

Istnieje wiele nieporozumień na temat tego, co „nieaktywna pamięć” oznacza w OS X. W przeciwieństwie do nieporozumień, nie cała nieaktywna pamięć jest pusta, nieużywana, buforowana lub usuwalna. W rzeczywistości pamięć aktywna może być również buforowana lub usuwalna, jeśli ostatnio była dostępna. Dużo nieaktywnej pamięci zawiera również dane, których nie można po prostu wyrzucić. Gdyby zostały odrzucone, programy uległyby awarii, ponieważ odrzucone strony zawierałyby prawidłowe dane (jak mówi cytat ze strony dewelopera OS X), a programy oczekują, że dane przechowywane w pamięci (wirtualnej) nie znikną.

Nieaktywna pamięć zawiera te same typy danych, co pamięć aktywna. Jedyną różnicą jest to, że OS X zauważył, że niektóre fragmenty pamięci nie były odczytywane ani zapisywane przez jakiś czas.

Powód, dla którego OS X klasyfikuje pewną pamięć jako nieaktywną, a inne regiony jako „aktywne”, ma związek ze stronicowaniem. Kiedy kończy się pamięć, będziesz musiał wydrukować niektóre dane. Pytanie brzmi, które dane? Jeśli odłożysz na bok dane, które program okazuje się natychmiast ponownie potrzebny, marnuje czas i niczego nie osiąga. Więc chcesz odrzucić pamięć, której program nie będzie musiał natychmiast użyć ponownie.

Przewidywanie, które strony mogą być niepotrzebne w przyszłości, jest trudne, ponieważ program może korzystać z pamięci wirtualnej w dowolny sposób i nie informować systemu operacyjnego o swoich planach. Ale jako heurystyka większość programów jest „lepkich” pod względem wykorzystania pamięci; jeśli od jakiegoś czasu nie korzystali z jakiejś pamięci, prawdopodobnie nadal nie będą korzystać z tej pamięci i nadal będą korzystać z pamięci, której ostatnio używali.

Kiedy więc system operacyjny decyduje się na wydrukowanie niektórych danych, przyjmuje strategię zamiany stron, które nie były ostatnio używane. Właśnie dlatego OS X dzieli pamięć zajmowaną przez programy na dwie grupy „aktywnych” i „nieaktywnych”. Powyżej pisał Link do strony programisty, jeśli w pełni odczytać, opowiada, jak ten proces się dzieje:

  • Kiedy zaczyna brakować pamięci, system operacyjny zaczyna przeglądać aktywne strony pamięci i ustawia flagę na każdej z nich.
  • Jeśli program odczytuje lub zapisuje na stronie, flaga jest usuwana.
  • Jeśli po pewnym czasie flaga nie zostanie wyczyszczona, strona zostanie posortowana w stos „nieaktywny”.
  • Jeśli program „otwiera” stronę „nieaktywną”, jest odkładany z powrotem na stos „aktywny”.
  • Kiedy skończy się pamięć, strony „nieaktywne” są stronicowane.

Należy pamiętać, że ten proces sortowania, aby zdecydować, którą pamięć należy wymienić, jest podobny we wszystkich nowoczesnych systemach operacyjnych. Linux ma te same dwie listy stron aktywnych i nieaktywnych, zgodnie z opisem w artykule Menedżer pamięci wirtualnej systemu Linux . Windows może użyć czegoś nieco innego z więcej niż dwiema klasami aktualności; Nie mogę obecnie znaleźć aktualnego, wiarygodnego opisu technicznego. Więcej implementacji omówiono na stronie Wikipedii zatytułowanej „Algorytm zastępowania stron” . Jedyną różnicą w systemie OS X był sposób wyświetlania statystyk: ktoś zdecydował, że dobrym pomysłem byłoby wyświetlenie osobnych liczb dla aktywnych i nieaktywnych w toplub Monitora aktywności. Z perspektywy czasu prawdopodobnie nie był to dobry pomysł (i zmieniło się to w OS X 10.9.)

Ten proces ustawiania i usuwania flag oraz utrzymywania aktywnych / nieaktywnych stosów wymaga trochę mocy procesora. Z tego powodu OS X nie robi tego, gdy jest dużo wolnej pamięci. Pierwsze uruchomione programy będą się wyświetlać jako cała „aktywna” pamięć, dopóki wolna pamięć nie zacznie się kończyć.

Tak więc, gdy zaczynasz od pustej tablicy i otwierasz coraz więcej programów, możesz spodziewać się następujących postępów w monitorze aktywności:

  • Po pierwsze, jest dużo „wolnej” pamięci i bardzo mało nieaktywna. Wynika to z faktu, że flagger pamięci nie zaczął działać.
  • Gdy ilość wolnej pamięci spada, OS X zacznie uruchamiać swój flagger pamięci i zaczniesz widzieć wzrost liczby „nieaktywnych”. Każdy bit „nieaktywny” był wcześniej „aktywny”.
  • Kiedy zabraknie wolnej pamięci, strony ze stosu „nieaktywnego” zostaną stronicowane. Flagger pamięci będzie również działał w pełnym przechyleniu, sortując pamięć na aktywne i nieaktywne. Zazwyczaj podczas zapisywania zamiany widać wiele „nieaktywnych”, co wskazuje, że flagger pamięci robi to, co powinien.

Strony musząbyć klasyfikowane jako nieaktywne, zanim zostaną wymienione. To właśnie oznacza cytat ze strony Apple Developer, gdy mówi: „Te strony zawierają prawidłowe dane, ale mogą zostać zwolnione z pamięci w dowolnym momencie”. Jest to sprzeczne z aktywnymi stronami, które nie zostaną wydane, dopóki nie zostaną zdegradowane do nieaktywnych. Istnieją różne sposoby zwalniania stron; jeśli strona została zmapowana z pliku i nie została zmodyfikowana, można ją natychmiast usunąć i ponownie odczytać na żądanie. Podobnie, jeśli jest to pamięć, która została wcześniej zamieniona i nie została zmodyfikowana od czasu zamiany. Programy mogą również jawnie alokować pamięć podręczną i pamięć usuwalną, aby przechowywać dane, które można zapomnieć i odtworzyć na żądanie (ale powód, dla którego program przydzielił pamięć podręczną jest, jeśli odtworzenie tych danych zajmuje dużo czasu.

Dlatego patrząc na ilość „nieaktywnej” pamięci w monitorze aktywności i widząc, że jest dużo nieaktywnych w tym samym czasie, gdy komputer pisze do wymiany, mówi tylko, że system działa zgodnie z przeznaczeniem.

Istnieje również zamieszanie między nieaktywną pamięcią a pamięcią podręczną plików. Nie jestem pewien, dlaczego jest to zamieszanie, ponieważ Monitor aktywności już je wymienia pod osobnymi nagłówkami. Pamięć podręczna to pamięć używana do przechowywania ostatnich danych, które zostały odczytane lub zapisane z systemu plików, na wypadek, gdyby trzeba było uzyskać do nich dostęp ponownie. Kiedy pamięć jest niska, OS X zwykle pozbywa się najpierw pamięci podręcznej. Jeśli masz wymiany lanie i monitorować aktywność wykazuje wielki stos pamięci podręcznej (nie nieaktywnej), a następnie , że byłby to problem. Ale nieaktywna pamięć to inna sprawa.

W razie wątpliwości zignoruj ​​różnicę między „nieaktywnym” a „aktywnym”. Uważaj je za jedną bryłę „pamięci używanej przez programy” i dodaj dwie liczby razem. To właśnie robi każdy inny system operacyjny, gdy mówi o zużyciu pamięci.

UWAGA dla OS X 10.9: Mavericks wprowadził „kompresję pamięci”, która jest mniej więcej kolejną warstwą wymiany. Aktywne strony są teraz klasyfikowane jako nieaktywne, następnie kompresowane (co może pojawiać się jako pamięć jądra w zależności od używanych narzędzi), a następnie zapisywane w celu zamiany wraz ze wzrostem użycia pamięci. Mavericks przestał także pokazywać osobne liczby dla aktywnych i nieaktywnych w Monitorze aktywności, ponieważ okazuje się, że nie jest to przydatna rzecz, na którą warto patrzeć, zwłaszcza biorąc pod uwagę nieporozumienia.


4

Obecnie nie ma łatwego sposobu na dostosowanie swapowania (lub tak się to nazywa) zachowania macos X. Istnieje jednak kilka hacków (wymaga konta programisty i pakietu SDK):

http://cestdelamerde.com/archives/22-Killing-Mac-OS-X-Swapping-How-To-Disable-dynamic_pager.html

http://dropsafe.crypticide.com/article/3848

Powodzenia!

Postscriptum. Myślę, że możesz przeczytać tę odpowiedź (również przeze mnie), aby uzyskać bardziej ogólny przegląd tego, co aktywne, nieaktywne i inne wspomnienia w MacOSX: Pamięć przewodowa vs. Pamięć aktywna w OS X


Dziękuję za twoje odpowiedzi. Dostosowanie swapiness z pewnością by pomogło - bez wątpienia nie jest to łatwe! Jeśli chodzi o pierwszy link, naprawdę szukam hacka, który nie obejmuje całkowitego wyłączenia swap / dynamic_pager i ponownego uruchomienia, ponieważ wymaga to zbyt wiele wysiłku, aby wyłączyć użycie swap, a także pozostawia system niestabilny, gdy zbliża się mała ilość nieaktywnej i wolnej pamięci. Drugi link odnosi się do problemu ciągle rosnących plików wymiany. Chociaż ważna kwestia, zwłaszcza gdy zaczyna brakować plików wymiany, nie jest tak naprawdę istotna dla mojego pytania w tym wątku ...
Motin

4

Nie jest to trwałe rozwiązanie, ale przynajmniej może pomóc odzyskać trochę nieaktywnej pamięci, potencjalnie unikając strasznej wymiany: http://itunes.apple.com/nz/app/freememory/id460931672?mt=12

Narzędzie jest bezpłatne i dość łatwe w użyciu. Po uruchomieniu wybierz opcję „Wolna pamięć” na pasku narzędzi / menu systemowym.

W przeciwieństwie do wyświetlacza pamięci ActivityMonitor pokazuje tylko wolną pamięć, co wydaje się lepszym wskaźnikiem zamiany trwającej lub nie.


Oceniam tę aplikację od czasu Twojej sugestii około dwa miesiące temu. Wygląda na to, że ta aplikacja rzeczywiście zwiększa ilość „wolnej” pamięci za pomocą różnych sztuczek, w tym agresywnie żądając dużej ilości pamięci, a następnie ją zwalniając. Powoduje to jednak zamianę tej samej ilości pamięci, którą „uwolniono”. To znaczy, że nie pomaga zwolnić pamięci, tylko przenosi zawartość pamięci z pamięci RAM na HD. W końcu powoduje to wiele zamian, gdy próbuję korzystać z aplikacji, które były otwarte podczas zwalniania pamięci, ponieważ wiele jego vm jest teraz w trakcie wymiany. :(
Motin

@Motin, korzystam z FreeMemory od miesięcy i tak nie jest, przynajmniej z mojego doświadczenia. Gdybym musiał wyuczać zgadywanie (na podstawie tego, co widziałem w Activity Monitor), różnica polega na tym, że FM najpierw zużywa „aktywną” pamięć, która ma pierwszeństwo przed buforami dysków. „Uwalnia” inną pamięć, ponieważ ma wyższy priorytet, a następnie uwalnia własną pamięć. Nigdy nie widziałem, żeby znacznie się zamieniało (być może niewielka ilość, która jest alokowana podczas konsumpcji).
powiek

2

Począwszy od systemu OS X 10.5 występują oczywiste problemy z zarządzaniem pamięcią w systemie MAC OS X. Sieć była już zaśmiecona skargami na gwałtowne spowolnienie systemu po pewnym czasie. Wtedy miałem wolniejszą maszynę, Mac Mini z 1 GB pamięci RAM, więc (błędnie) doszedłem do wniosku, że to z powodu gorszego sprzętu.

Teraz mam 2010 MBP, rdzeń i7, 8 GB pamięci RAM, podwójny procesor graficzny. Mac OS X Snow Leopard sprawiał ból, ale po migracji do OS X Lion praca nad poważnymi rzeczami na MACie stała się koszmarem.

W końcu udało mi się odtworzyć problematyczny scenariusz, więc uruchomiłem test i nagrałem ekran na wideo.

Problem z wydajnością MAC OS X Lion - zepsute zarządzanie pamięcią

Uruchamiam komendę tar + bzip, która jest podstawową rzeczą uniksową, na dużej liczbie plików obrazów w moim folderze Pictures /. Tuż przed uruchomieniem uruchamiam polecenie „purge”, aby usunąć nieaktywne / buforowane dane programu.

Na filmie widać, że wolna pamięć zaczyna spadać bardzo szybko, a nieaktywność stale rośnie. Jeśli spojrzysz na polecenie „bsdtar”, zajmuje to tylko fragment pamięci RAM, więc problem nie występuje w tym procesie. Nie można powiedzieć, że jest to wyciek pamięci programu, ponieważ wtedy problemem nie byłby nieaktywny RAM, a raczej aktywny / przewodowy.

Gdy wolna pamięć spadła poniżej 100 MB, uruchomiłem niektóre aplikacje, takie jak Safari, iPhoto i MS Word, i widać na filmie, że uruchomienie aplikacji zajmuje nawet minuty, gdy normalnie (gdy jest wolna pamięć RAM), to ładowanie zajmie około 3-5 sekund.

W moim Linux Centos 6 uruchamiam ten sam scenariusz i te same polecenia, nie ma problemu! Zużycie pamięci wynosi około 10-20 MB, bez problemów z pamięcią podręczną / buforem.

Zarządzanie pamięcią musi być bardzo zepsute w Mac OS X!


2
To, co widzisz, to system buforujący pliki w pamięci. Zgadzam się, że istnieje problem polegający na tym, że pamięć podręczna nigdy nie wydaje się zostać wyczyszczona ... ale samo buforowanie (aw konsekwencji wzrost nieaktywnej pamięci) jest rozsądną i czasem użyteczną funkcją wydajności.
powiek

Również środowisko testowe jest dalekie od sterylności. Nie możemy powiedzieć, co robi QuickTime Player ani żaden z innych programów jest otwarty.
chrishiestand

1

Założę się, że nie ma na to właściwej odpowiedzi. Podobnie jest z pamięcią, która pozostaje aktywna po uśpieniu komputera Mac, po prostu rośnie i rośnie z każdym snem.

Po stronie „zabawy” (czyli drogiej) możesz ulepszyć pamięć lub wymienić dysk twardy na dysk SSD, aby wymiana nie była hitem wydajności. Wybrałem pierwszą opcję, ponieważ pamięć Corsair jest teraz dostępna w rozsądnej cenie.

16 GB pamięci RAM


2
Pamiętaj, że dyski SSD mają ograniczone cykle zapisu. Należy również pamiętać, że w przypadku dysków SSD bez funkcji przycinania zapisy mogą ostatecznie być kosztowne, ponieważ komórkę Flash trzeba usunąć.
Wavy Crab

Czy możesz zacytować źródło problemu „Uśpienie powoduje zwiększenie zużycia pamięci”?
GordonM,

Czy mogę przytoczyć swoje doświadczenie? :) Przeprowadziłem szybkie wyszukiwanie i znalazłem to: dyskusje.apple.com/message/21624847#21624847 + istnieje wiele tematów związanych z nieaktywną pamięcią, które nie są usuwane w razie potrzeby. Osobiście widziałem, jak po każdym śnie nieaktywna pamięć pozostaje taka, jaka była wcześniej i wzrasta. „purge” jest opcją, ale nie chciałbym czyścić nieaktywnej pamięci raz na 20 minut (założę się, że tak byłoby w przypadku 4 GiB RAM).

1
@Dyski SSD WavyCrab mogą mieć ograniczone cykle zapisu, ale nie ma szans, że kiedykolwiek osiągniesz ten limit. Nie martwiłbym się tym, chyba że jest to dysk SSD dla centrum danych. W każdym razie, jeśli zamierzasz obniżyć dysk SSD przez nadmierne zapisywanie, wcześniej zmniejszysz dysk twardy.
andreadi
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.