Czy zaawansowane gry w javie byłyby mniej wydajne od tych napisanych np. w c++?

Odpowiedz Nowy wątek
ffffffffff
2014-08-17 18:47
ffffffffff
0

W javie to znam minecrafta i właściwie tyle gier nie licząc mniejszych. Nie znam żadnych gier z grafiką jak w call of duty, battlefieldy, crysis.
Czy gdyby twórcy gry Crysis 3 (DX11) napisali identyczną grę w Javie, to czy wydajność Crysis 3 w Javie byłaby taka sama, czy gorsza, albo dużoooo gorsza i wręcz niegrywalna?

Pozostało 580 znaków

2014-08-17 19:19

Rejestracja: 8 lat temu

Ostatnio: 2 dni temu

1

w javie nie ma zarzadzaniem pamieci recznej. Jest Garbage Collector. Wyobraz sobie ze grasz i co jakis czas gra Ci zamraza bo musi wyczyscic to co zadelkarowal program

zreszta
naucz sie szukac sam odpowiedzi bo byla juz milion razy

w google wpisujemy
why games are not written in java

pierwszy link
http://stackoverflow.com/ques[...]t-video-games-written-in-java

Pozostało 580 znaków

msm
2014-08-19 22:53
msm
Administrator

Rejestracja: 10 lat temu

Ostatnio: 1 dzień temu

12

Czy gdyby twórcy gry Crysis 3 (DX11) napisali identyczną grę w Javie, to czy wydajność Crysis 3 w Javie byłaby taka sama, czy gorsza, albo dużoooo gorsza i wręcz niegrywalna?

Wydaje mi się że Twórcy Gry Crysis 3 to programiści C++ (a przynajmniej ta część twórców która programuje), więc gdyby napisali grę w Javie to byłaby dużoooo gorsza i wręcz niegrywalna.

w javie nie ma zarzadzaniem pamieci recznej. Jest Garbage Collector. Wyobraz sobie ze grasz i co jakis czas gra Ci zamraza bo musi wyczyscic to co zadelkarowal program

Kontrargument (tak, to C#, ale przypadek wystarczająco podobny):
http://unity3d.com/showcase/gallery

Jeśli chodzi o programowanie gier w językach z GC: sam zaczynając programować interesowałem się grami (jak niejeden pewnie), tylko zamiast grać wolałem je tworzyć. No więc na temat podejść do pisania gier w C#:

Po pierwsze: nie alokować (a.k.a. /hackować/ zamiast alokować)
Najprostsze koncepcyjnie i najbardziej ekstremalne podejście - nie alokować nic. A konkretnie nie alokować nic w pętli głównej gry (zdarzenia dynamiczne jakby nie próbować, nową pamięć brać muszą, ale tak jest wszędzie). Żeby to osiągnąć trzeba:

  • cachować obiekty (tzw. object pools). Ilość typów obiektów w grze jest ograniczona. Po prostu zamiast pisać obj = new Obiekt() można pisać obj = Cache<Obiekt>.Create() (...oraz Cache<obiekt>.Free(obj) - i mamy wszystkie problemy pilnowania pamięci w zarządzanym świecie - świetnie). Jest to dużo wolniejsze (i brzydsze) niż "prawdziwe new" w C# (ktore 99.5% czasu jest równie szybką operacją co np. dodawanie)
  • używać struktur gdzie się da/gdzie to ma sens (ok, to się na javę nie przenosi). Struktury są alokowane na stosie zamiast na stercie, ale jest catch - JIT jest optymalizowany pod typowe przypadki, a typowym przypadkiem w C# są klasy. Z tego powodu sporo koniecznych optymalizacji nie działa dla value types (np. inlining! Przy prymitywnych operacjach jak np. dodawanie wektorów to znaczący problem), i albo mamy wolny kod (poza tym że samo przekazywanie sturktur jest wolniejsze niż klas), albo używamy hacków (jak przekazywanie struktur przez referencję).
  • przepisywać funkcje z biblioteki standardowej od zera. Cóż, większość funkcji "leakuje" pamięć, więc jeśli chcemy "całą dla nas", trzeba je napisać samodzielnie zamiast koncentrować się na pisaniu gry.
    disclaimer: nie piszę co robić. Piszę co można zrobić. Żeby nie było że promuję kod nadający się do programistycznego WTF

Po drugie: alokować mało lub krótko
Pogłoski o tym że GC w trakcie gry to śmierć są mocno przesadzone. Nie znam się na ekosystemie i technologiach w świecie javy, więc znowu od strony dotnetu, jak to naprawdę jest z GC:

  • GC gen 0 jest szybki. Mokrym snem projektantów było to żeby zajmował nie więcej czasu niż zwykły cache miss - jesteśmy "not quite there yet", ale to coś na co trzeba zwrócić uwagę - po to obiekty są podzielone na generacje żeby typowy GC wykonywał się w mgnienie oka.
  • z Gen1 i Gen2 nie ma już tak fajnie. Ale to może nie być problemem, jeśli obiekty nie przeżywają gen0 - to znaczy jeśli wszystkie obiekty w grze są albo bardzo ulotne (np. żywe jedną klatkę gry), albo trwałe (np. żywe cały level) to te kolekcje mogą wcale nie nastąpić.
  • z uwag odnośnie GC, sam nie benchmarkowałem nigdy (ani nie korzystałem świadomie) ale podobno duże znaczenia ma ilość rootów (korzeni?) GC. Root = wszystko co globalne zasadniczo (czyli rzeczy statyczne), czyli rzeczy od których GC zaczyna czyszczenie i które musi przejrzeć za każdym razem.
  • jeszcze więcej uwag odnośnie GC. Dotnetowy GC (javowcy też chyba mają analogiczną mechanikę) korzysta z techniki write-barrier, przy pomocy struktury danych nazywającej się cardtable. Cardtable to po prostu tablica bitów, gdzie każdy bit odpowiada pewnemu obszarowi pamięci (np. 1 kb). Zapisanie czegoś do obiektu z niezerowej generacji powoduje zapalenie bitu w cardtable odpowiadającemu pamięci gdzie znajduje się ten obiekt (piszę po polsku? Inaczej ujmując, cardtable mówi mniej-więcej które obszary pamięci zostały zmodyfikowane). Dzięki temu np. GC wykonując mark&sweep w gen1/gen2 ma uproszczoną robotę. Nigdy z tego celowo nie skoszystałem (i nie polecam), ale kolejny przykład na to że GC nie jest musi być głupi.

Po trzecie: skoro trzeba to alokować

  • GC gen 2 jest wolny. Ale od czego są wątki? Od początków dotnetu GC może działać w wielu trybach. Domyślnym z nich do .net 4.5 był concurrent. Dzięki temu przy GC gen 2 większość operacji jest wykonywana równolegle, wątki zatrzymywane są tylko po to żeby poprawić referencje po wykonanej robocie (chyba że wyczerpią ephemeral segment, bo GC gen1 i GC gen0 nie mogą być wykonywać się równocześnie z concurrent GC.
  • GC gen 2 jest wolny. Ale od czego są wątki! Od .net 4.5 domyślnym trybem GC jest nowy 'cutting edge' tryb Background. Background GC potrafi wykonywać jednocześnie GC gen1/gen0 oraz GC gen2 (dodatkowo w server mode na każdy procesor przypada jeden wątek GC, ale to akurat nie dotyczy gier). Przerwy na GC 2 robią się jeszcze krótsze. (Dla ciekawych - http://blogs.msdn.com/b/dotne[...]r-client-and-server-apps.aspx)

Chętnie napisałbym więcej o GC (a jest o czym - brick tables, Large Object Heap, problemy z pinowaniem, managed pointers, finalizacją i rezurekcją, thread hijacking...) ale to by był OT i w dodatku specyficzny dla .net a pytanie o javę ;).

Podsumowanie: czy warto?
Tak chciałem rzucić losowe rzeczy które mi przyszły do głowy z tego co robiłem. Wracając do tematu - gdyby pytanie było po prostu o pisanie gier (gry na komórkę, minigry, gry webowe/flashowe) to odpowiedź byłaby oczywista (że warto - ignorując większość uwag o wydaności z tego posta. Po prostu przy zwykłych grach to nie taki problem).
Z drugiej strony skoro mówimy o "zaawansowanych" grach, czyli grach "przesuwających granicę tego co możliwe" (jak pamiętam np. Crysisa) - nie jestem przekonany (no i pewnie ilosć programistów C#/Javy znających się na pisaniu gier jest... nikła. Podobnie jak wsparcie, chociaż w przypadku C# dzięki Unity to się zmienia). Może i DA SIĘ pisać wydajnie, ale tak naprawdę pytanie jest czy opłaca się to robić.
A z trzeciej strony to i tak jakość współczesnych gier obecnie ogranicza nie wydajność PC tylko konsole (które są ważniejsze z punktu widzenia producentów) ;)

PS. jeszcze zostawię to tutaj: http://superhotgame.com/ (unity)

edit: łał, ale mi post wyszedł. W dodatku rozpisałem się o GC zamiast odpowiadać na pytanie. Cóż, każdy ma jakieś hobby - jedni interesują się samochodami, inni Garbage Collectorami ;).

edytowany 1x, ostatnio: msm, 2014-08-19 22:55
Fajnie, wiedzy o .NETowej śmieciarce nigdy za wiele ;) - AlfaLeporis 2014-08-19 23:04
zaden kontrargument z unity3d. Silnik jest napisany w c++. Skrypty piszesz w c#. W kazdym silniku, baaa w kazdej wielkiej grze AAA nikt o zdrowych rozsadkach nie bedzie pisal w czystym c++ tylko bedzie do tego skryptowy jezyk (unity dodalo c# jako skryptowy jezyk). A silnik napisze sie w c / c++ - fasadin 2014-08-20 09:33
drugie spostrzezenie, zawsze pisze sie wlasny stl (jezeli chodzi o c++) wiec przepisywanie kolekcji i ogolnie funkcji ktore sa. Nie jest niczym szczegolnym :) - fasadin 2014-08-20 09:36
I nie tylko C#, boo i js też (a w sumie ichnią odmianę js). Fakt, to zupełnie co innego (czyli w sumie temat o pisaniu /silników/ do gier). Ogólnie myślą przewodnią postu (którą trochę zgubiłem, ale.) było to że problemy z GC w grach da się obejść, tylko że okazuje się wtedy że pisze się prawie jak w C++ i do tego walcząc co chwilę z językiem (który nie jest przeznaczony za bardzo do takiego użycia) ;). Ad. przepisywania STL to ciekawe, nie wiedziałem (ale nie znam się na gamedevie) - dlaczego 'standardowy' STL nie wystarcza (zoptymalizowany raczej jest, więc coś innego?)? - msm 2014-08-20 09:44
Przedewszystkim jest alokowana pamiec na stercie. Co jest wolniejsza operacja niz alokowanie na stosie malych obiektow (ale tak wiem, mozna swoj wlasny alokator napisac). Ale informacje moje byly juz niepoprawne :) Zawsze to slyszalem, jednak prawda jest troszke inna. http://gamedev.stackexchange.[...]/268/stl-for-games-yea-or-nay Zaakceptowana odpowiedz. Do tego dochodzi jeszcze http://www.open-std.org/jtc1/[...]1/docs/papers/2007/n2271.html STL pod konsole. No i jeszcze problem z stlem teraz jest. Ze jest inny dla gcc, msvc, intel itd itp. - fasadin 2014-08-20 10:07
"zawsze pisze sie wlasny stl" - ja myślę że taki Boost ma tyle wariantów różnych kontenerów, że któryś nada w konkretnym zastosowaniu i nie trzeba pisać od zera. - Azarien 2014-08-20 11:09

Pozostało 580 znaków

fsadsafdfdsa
2014-08-21 09:08
fsadsafdfdsa
0
fasadin napisał(a):

w javie nie ma zarzadzaniem pamieci recznej. Jest Garbage Collector. Wyobraz sobie ze grasz i co jakis czas gra Ci zamraza bo musi wyczyscic to co zadelkarowal program

a co chcesz deklarować przy rysowaniu? przecież nie będziesz tworzyć przeciwników przy każdej klatce obrazu; przy ładowaniu poziomu tworzysz obiekty, później je tylko przesuwasz; ewentualnie doczytujesz mapę w którymś miejscu ale przecież nie musisz tego robić cały czas

ostatnio chyba nawet na tym forum ktoś miał problem przycinania się co którąś klatkę gry - rozwiązaniem było ręczne odpalanie GC co klatkę; w ten sposób gra działała niezauważalnie wolniej ale bez przycięć

kod zarządzany po kilkukrotnym odpaleniu zazwyczaj jest tak samo szybki jak natywny
ba - nawet widziałem że javascript potrafi być szybszy od c++

Pojawila sie jakas nowosc w Javie ze mozna GC recznie wywolac? (dawniej to bylo tylko pobozne zyczenie aby sie wywolal) - WhiteLightning 2014-08-21 09:18
Nie wiem czemu, ale jak dla mnie - w tym temacie - wygląda to mniej więcej tak: "Haha, tato, tym razem byłem lepszy!"'; "Tak tak synku, dobra robota :]" - spartanPAGE 2014-08-21 09:32
Od zawsze można w Javie GC ręcznie wywołać. System.gc() (specyfikacja stwierdza, że jest to tylko "hint" i nie musi działać, ale fakty są takie, że implementacja od Oracle zawsze wywoływała GC przy tym wywołaniu, o ile ktoś specjalnie tego nie wyłączył w opcjach aplikacji). Natomiast inna rzecz, że jeśli musisz to robić, to na pewno robisz coś źle i problem leży gdzie indziej. - Krolik 2014-08-21 20:59

Pozostało 580 znaków

2014-08-21 09:25
Moderator

Rejestracja: 16 lat temu

Ostatnio: 1 godzina temu

0

@fsadsafdfdsa nie przesadzajmy. JIT to jest fajna rzecz, ale jest mocno empiryczna, niedeterministyczna i w jednej sytuacji przyspieszy kod 10 razy a w innej ani trochę.
Dla tych którzy nie wierzą że język z JIT (np. Java czy Python) mogą być szybsze niż C/C++, nawet pomimo tego że mają narzut maszyny wirtualnej, krótkie wyjaśnienie:

  1. Kompilator języka natywnego może dokonać optymalizacji tylko w czasie kompilacji. W trakcie uruchomienia jest już tylko kod maszynowy interpretowany przez procesor.
  2. Środowisko wykonania dla języków z kodem pośrednim może dokonywać optymalizacji także w trakcie wykonania programu, w trakcie tłumaczenia bajtkodu na kod maszynowy. To jest właśnie JIT - kompilacja Just in Time
    Krótki przykład jak sprawić żeby Java była szybsza niż C. Wyobraźmy sobie że mamy kod który wykonuje miliardy operacji dzielenia przez zmienną podaną przez użytkownika. Kompilator C/C++ niewiele może tu zoptymalizować, w końcu nie wiadomo przez co będziemy dzielić. Co się dzieje jeśli użytkownik poda jako dzielnik liczbę 2? Kod w C/C++ będzie działał identycznie niezależnie od podanej liczby. Kompilator JIT w Javie będzie za to w stanie wykryć że dzielimy przez 2 i będzie mógł zamienić te wszystkie operacje dzielenia na dużo szybsze przesunięcia bitowe. I voila, kod w Javie pomyka szybciej niż kod natywny.

Przykład jest oczywiście przejaskrawiony, ale wcale nie taki nierealny. Ciekawostka: interpreter CPython jest ~5 razy wolniejszy od interpretera PyPy właśnie dlatego że ten drugi posiada kompilator JIT.

Jeśli chodzi o GC to kolejne generacje tych narzędzi są coraz lepsze, nie ma już efektu stop-the-world itd. Nie zmienia to oczywiście faktu że mimo to pewien narzut istnieje. Ale z drugiej strony szansa na wycieki jest dużo mniejsza, czas debugowania też :)


Masz problem? Pisz na forum, nie do mnie. Nie masz problemów? Kup komputer...

Pozostało 580 znaków

2014-08-21 09:50

Rejestracja: 12 lat temu

Ostatnio: 2 dni temu

0

Dużo zależy od konkretnego problemu. Zapewne znacznie szybciej napiszesz grę, która będzie miała ograniczoną grafikę (kosztowne obliczenia realizowane GPU, z którymi java sobie średnio radzi) i dużó AI (planszóweczki w stylu Panzer General czy HoMMIII) niż takiego Crysisa

W Javie można zarządzać pamiecią "ręcznie" za pomocą klasy Unsafe > http://www.slideshare.net/mishadoff/unsafe-java-18168628 oczywiście przypomina to sekswakacje w Tajlandii bez użycia gumy, ale zawsze...

Kolejna rzecz to algorytmy i ich implementacja. To już jest czynnik ludzki i dużo zależy od tego kto pisze kod. Mam takie wrażenie, że programiści C++ sa w tym lepsi niż javowcy.

JIT, jak wspomniano powyżej pozwala na optymalizację w czasie wykonania i pewne związane z tym bonusy.

"Mam takie wrażenie, że programiści C++ sa w tym lepsi niż javowcy." Nie chcę tu jakiegoś flame'a robić, ale z ciekawości - po czym wnosisz? Bo ja mam dokładnie odwrotne wrażenie. Tzn. większość programistów C/C++ jakich znam, to świeżo upieczeni absolwenci, którzy znają C++ bo było obowiązkowe na studiach, i którzy z wyższością patrzą na Javę, której nie znają (no, bo tylko jeden fakultet mieli, na którym napisali hello-world i było wolniejsze niż C, przeto Java jest powolna i się do niczego nie nadaje). - Krolik 2014-08-21 21:03
Mówię o ludziach z kilkuletnim już stażem. Po prostu trochę inna specyfika tworzonych aplikacji powoduje, że programiści c++ nabywają praktycznych umiejętności w zakresie np. matematyki "graficznej" czy implementacji algorytmów z zakresu fizyki w wydajny sposób. Javowcy za to znacznie lepiej ogarniają problemy związane ze specyfiką aplikacji biznesowych. Dla nich ogarnięcie złożonego przepływu na poziomie biznesowym nie jest problemem. Mają odpowiednie narzędzia i wiedzę. - Koziołek 2014-08-21 21:28

Pozostało 580 znaków

2014-08-21 10:13

Rejestracja: 8 lat temu

Ostatnio: 2 dni temu

0
<student> Java jest szybsza od C++. W C++ nie ma JIT <inny student="student"> i java zjada mniej pamięci niż C++. Bo w C++ nie ma garbage collector edit. Zaraz opisze sie ;) takze za godzinke bedzie tu cos dlaczego c#/java nie sa dobre jak c++. C++ jest natywnym jezykiem programowania z "runtime library" wiec kiedy aplikacja w c++ jest wywolywana w maszynowym kodzie uzywa funkcji z "runtime" i to jest kompletnie oddzielone od OS aplikacji. To zyje w swoich wlasnych procesach/watkach i uzywa zasobow systemowych jako standardowa aplikacje na OS. Aplikacja jest zrobiona pod konkretnego OS z c#/java jest inaczej, na poczatku sa uruchamiane za pomoca byte-codu i ten byte code jest jedyna rzecza ktora jest natywna. wtedy aplikacja napisana przez nas, jest przekazywana do runtime. Runtime tlumaczy kod na maszynowy i go wykonuje. To jest ogolna idea, ale jest tego troszke wiecej. Kazdy zasob systemowy jest wrappowany przez runtime sybsystem. Wiec kazde wywolanie bedzie liczba "wrapow" dla tych sub-calls W c/c++ mozemy powiedziec ze "ta linia jest tlumaczona na N op-codes" w c# java mozemy powiedziec podobnie ze ta linia zostala przetlumaczona na M op-codow. ALE zawsze M>N Niektorzy moga powiedziec "to nie jest prawda daj mi algorytm i zrobie M=N". Zgadza sie, nawet moga byc to te same algorytmy, ale jezeli chodzi o prawdziwe aplikacje jak np gra napisana w openGL wtedy to nie jest mozliwe chocby ze wzgledu na architekture Ponownie mozecie powiedziec "to nie prawda" ale przy nastepnej optymalizacji znajdzie sie asm, c++ itd i juz nie bedzie to dluzej natywny kod c#/java No i kolejna rzecz. Bezpieczenstwo. W roznych frameworkach pojawiaja sie bugi calkiem czesto. Jezeli ktos znajdzie takie cos, wszystki applikacje sa narazone. I co mozesz zrobic? Tak na prawde nic, z wyjatkiem modlenia sie. Bugi w c++ w runtime oczywiste tez sa mozliwe, ale sa bardzo rzadkie i mozesz napisac dla nich "workaround" dla prawie kazdego przypadku. No i bugi w c++ sa raczej naprawiane super wczesnie - poniewaz ten bug zapewne tez bedzie w danym OS
edytowany 2x, ostatnio: fasadin, 2014-08-21 10:29

Pozostało 580 znaków

2014-08-21 11:01
Moderator

Rejestracja: 16 lat temu

Ostatnio: 1 godzina temu

0

@fasadin

  1. Może i M>N ale generalnie niekoniecznie jest to wielka różnica.
  2. Nie rozumiem fragmentu o frameworkach. Porównujesz frameworki z gołym językiem. Przeciez we frameworkach C++ też mogą być bugi i to jeszcze groźniejsze bo java mimo wszystko działa w pewnym sandboxie maszyny wirtualnej.

Masz problem? Pisz na forum, nie do mnie. Nie masz problemów? Kup komputer...
Ja bym jeszcze dorzucił trochę inną kulturę kodowania w Javie. - Koziołek 2014-08-21 11:18

Pozostało 580 znaków

2014-08-21 21:12
Moderator

Rejestracja: 15 lat temu

Ostatnio: 5 godzin temu

3

W c/c++ mozemy powiedziec ze "ta linia jest tlumaczona na N op-codes" w c# java mozemy powiedziec podobnie ze ta linia zostala przetlumaczona na M op-codow. ALE zawsze M>N

To jest akurat w ogólności nieprawda. Może być zarówno M < N, M == N jak i M > N. Wszystko zależy od tego, jakie optymalizacje wykona kompilator. A do tego więcej opcodów nie zawsze oznacza wolniejsze wykonanie, bo procesory robią pod spodem kolejną warstwę optymalizacji (np. zmieniają kolejność wykonania), więc wnioskowanie na tej podstawie o wydajności nie jest słuszne.

Bezpieczenstwo. W roznych frameworkach pojawiaja sie bugi calkiem czesto. Jezeli ktos znajdzie takie cos, wszystki applikacje sa narazone. I co mozesz zrobic? Tak na prawde nic, z wyjatkiem modlenia sie. Bugi w c++ w runtime oczywiste tez sa mozliwe, ale sa bardzo rzadkie i mozesz napisac dla nich "workaround" dla prawie kazdego przypadku. No i bugi w c++ sa raczej naprawiane super wczesnie - poniewaz ten bug zapewne tez bedzie w danym OS

No, tak bo w takim Qt, gcc czy przeglądarce internetowej to nie ma setek niepoprawionych bugów.
Język w którym każdy kawałek kodu może nadpisać dowolny fragment swojej pamięci nazywasz bezpiecznym.... ROTFL.

Jak musz buga w C++, to faktycznie możesz się tylko modlić aby nie rozwalił sterty i nie zakończył się crashem. W Javie łapiesz wyjątek i jedziesz dalej.

Odpowiadając na oryginalne pytanie:

  1. GC raczej nie jest już problemem. CMS odśmieca współbieżnie i jak się jest ostrożnym można spokojnie zejść z do poziomu pojedynczych milisekund raz na jakiś długi czas. Jak komuś CMS nie daje rady, to można próbować z G1, ale moje doświadczenia są lepsze z CMS. Gry używają bardzo dużo pamięci na zasoby graficzne. Można je alokować poza stertą, nie obciążając GC.

  2. Nadal problemem jest optymalizowanie struktur danych aby były cache-friendly. Java nie ma value-types tak jak ma C#. To powoduje, że trudno zrobić wydajną reprezentację punktów (np. Point3D). Ale z tego co wiem, to pracują nad tym i w niedalekiej przyszłości ten brak zostanie naprawiony (raczej nie w Java 9, a później, ale zostało to już ogłoszone).

  3. Większość dobrych silników została napisana w C/C++, więc z przyczyn historycznych, zaawansowane gry pisze się w tym, co jest wymagane przez silnik.

  4. Przykład Minecrafta pokazuje, że gracze wcale nie są tak bardzo wrażliwi na okazjonalne lagi i przycięcia, jak to niektórzy sugerują. Jak gra jest dobra, to zgubienie jednej klatki raz na 5 minut nie jest jakimś wielkim problemem.

i java zjada mniej pamięci niż C++. Bo w C++ nie ma garbage collector

W pewnym sensie jest to prawda. Tzn. licząc tylko samą stertę, system z GC jest znacznie bardziej przewidywalny pamięciowo niż system z alokacją dynamiczną malloc/free. W przypadku ręcznej alokacji tak jak w C++, tak naprawdę nie masz żadnej gwarancji, że rozmiar sterty jest tylko nieznacznie większy od rozmiaru pamięci faktycznie zaalokowanej. Pogooglaj o problemie fragmentacji pamięci. Typowo fragmentacja nie jest dużym problemem, ale w skrajnym przypadku może się zdarzyć, że Twój program będzie zżerał w danej chwili 100x więcej pamięci niż faktycznie jest zaalokowane. Natomiast w przypadku GC - TY jako programista aplikacji możesz na sztywno wbić jaki chcesz mieć ten współczynnik (całkowity rozmiar sterty / używana pamięć) i w dobrze napisanej aplikacji 1.5x zapewnia zwykle bardzo dobrą wydajność i małą aktywność GC. Jak dasz za mało miejsca na GC, to najwyżej się w którymś momencie przytnie. W C++, gdybyś tak zrobił (hmm... da sie - wystarczy odpowiedni ulimit), dostajesz wyjątkiem, a raczej wywaleniem programu, no bo kto łapie wyjątki rzucane przez new?

Inna sprawa, że systemy z GC mają większą przepustowość (w sensie allocation/deallocation rate) niż systemy z ręczną alokacją. Swoją drogą systemy baz danych od dawna stosują coś w rodzaju GC, właśnie aby zwiększyć wydajność. Jak robisz DELETE w SQLu, to dane nie są usuwane natychmiast, tylko doppiero podczas GC (w Postgresie zwanego "vacuum" a w Cassandrze "compaction").

edytowany 8x, ostatnio: Krolik, 2014-08-21 21:42
Pokaż pozostałe 2 komentarze
Placement new nie jest uniwersalną strategią zarządzania pamięcią, nadaje się tylko w niektórych przypadkach. Javowe GC działa jak placement new, ale dla wszystkich obiektów (alokuje sekwencyjnie z ciągłego obszaru, a po jakimś czasie zwalnia cały obszar za jednym zamachem). Dlatego wcale nie jestem przekonany, czy tuning GC nie jest ogólnie łatwiejszy niż zabawy w placement new, pule obiektów i inne dziwne rzeczy w C++. Np. LMAX z premedytacją użył Javy, bo stwierdzili, że łatwiej jest zoptymalizować GC niż optymalizować C++ pozbywając się do tego bezpieczeństwa pamięci. - Krolik 2014-08-22 08:36
Ale jakie zabawy z placement new? To po prostu wcześniejsze zarezerwowanie sobie miejsca, nic więcej. Proste jak budowa cepa, a i tak co możesz masz na stosie - spartanPAGE 2014-08-22 09:50
No wcześniejsze zarezerwowanie miejsca, miejsce się kończy i wtedy co? Jak się okaże, że część obiektów nadal potrzebujesz, a część nie, to jesteś w punkcie wyjścia - piszesz albo ręczny alokator ala malloc/free i pamiętasz, gdzie są wolne miejsca (fragmentacja), albo robisz coś w rodzaju GC, gdzie przenosisz używane obiekty do nowego regionu, aktualizujesz do nich wszystkie referencje, a stary zwalniasz. I to już wcale nie jest proste. Innymi słowy mnóstwo kodu na coś, co GC w Javie robi za Ciebie bezpieczniej bez pisania ani jednej linijki. - Krolik 2014-08-22 10:54
Huh? Wybierasz sobie wielkość sterty i na tym kończy się zabawa. Nie wiem jaką magie chcesz tutaj przypisać, nie mniej jednak przypominam, że mówimy tutaj o grach - tyle stworzono, wszystkim pasowało; http://gameprogrammingpatterns.com/object-pool.html - spartanPAGE 2014-08-22 11:12
Teraz piszesz o puli obiektów, a nie placement new. Tylko że pulę obiektów można tak samo zrobić w Javie, C# a nawet w Pythonie. Więc znowu nie widzę tu za bardzo jakiejkolwiek przewagi. Pule obiektów jednak niekoniecznie są szybsze od GC, zwłaszcza dla małych obiektów, bo masz narzut na wyszukanie i wyciągnięcie wolnego obiektu z puli, a zakodowanie takiej puli bezpiecznie ze względu na wątki i do tego wydajnie jest już całkiem skomplikowane. - Krolik 2014-08-22 11:46

Pozostało 580 znaków

2014-08-22 09:03

Rejestracja: 8 lat temu

Ostatnio: 1 godzina temu

1

Dochodzi jeszcze jedna rzecz - wiedza i nauka. Jesli jest zespol gosci ktorzy od 10 lat wymataja robiac gry w C/C++ i maja w malym paluszku cala potrzebna im wiedze, to przejscie na nowa technologie zajmie sporo czasu (prototyp czy alfe zrobia szybko, ale potem na walce ze szczaegolami i drobiazgami mnostwo zejdzie).

Dlatego w czasach, kiedy o Javie nikt nie słyszał, a w biznesie rządziło C++, w gamedev twardo kodowali w C i asm (no i flamewary C++ vs C były na porządku dziennym, gdzie wobec C++ stosowano podobną krytykę co obecnie wobec .NET i Javy - że nie daje pełnej kontroli, że dużo robi "za plecami programisty", że daje dodatkowy narzut na abstrakcje itp.) - Krolik 2014-08-22 10:58
Zgadzam sie, stad teraz robi sie rozbicie technologii w gamedev, czesc osob (zwlaszcza projekty AAA) zostaje w okolicach C/C++. A czesc (szczegolnie male projekty czy indie) idzie w srodowiska typu Unity, bo tam tworzy sie szybko, a wydajnosc przewaznie jest wystarczajaca. Dochodzi tez wykorzystanie gotowych silnikow a one przewaznie sa robione w C++. - WhiteLightning 2014-08-22 11:21

Pozostało 580 znaków

CcCcC
2014-08-22 11:57
CcCcC
0

W Javie nie można napisać Javy!!! Nie można w niej napisać nic, co potrzebne było, by napisać Javę!!! Ani nic, co potrzebne było do napisania tego, co potrzebne było... etc. Potrzebujesz VM i potrzebuejsz coś, na czym VM będzie działać. Ani VM ani Javy, ani tego na czym to działa, nie możesz napisać w Javie. A żeby uruchomić VM... o, potrzeba całkiem sporawo.
Java jest najbardziej zasobożerna...
Java jest najbardziej rozwlekła...
Java jest najbardziej powolnym językiem...

Pozostało 580 znaków

Odpowiedz

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0