Safari 페이지가 iOS 렌더링을 중단하는 이유는 무엇입니까?


79

나는 제목이 그다지 설명 적이 지 않다는 것을 알고 있지만 여기에 이야기가 있습니다. 주로 JavaScript와 Mapbox 라이브러리를 사용하여 브라우저 게임을 개발하고 있습니다.

데스크톱, Android 및 iOS에서 모든 것이 잘 작동하지만 iOS에서는 한 가지 문제가 나타납니다. 게임을 몇 분 동안 실행 한 후 갑자기 전화에 그래픽 아티팩트가 나타나고 대부분의 텍스트가 뒤섞여 표시됩니다.

다음은 전화가 시작되는 모습에 대한 사진입니다. 여기에 이미지 설명 입력 여기에 이미지 설명 입력 여기에 이미지 설명 입력

내 질문 은 : 내 코드에서 정확히 무엇이 이것을 일으킬 수 있습니까? 메모리 누수? ( LE : 실제로 메모리 누수로 밝혀졌습니다.)
진짜 질문 은 어떻게하면 단순히 웹 페이지를 검색하는 것으로 전체 전화기를 거의 브릭 킹 할 수 있다는 것입니다. 사파리가 이것을 막아야하지 않나요? 아니면 적어도 iOS 는요?

이 문제는 다른 iPhone 장치에서 재현 될 수 있으므로이 특정 장치의 문제가 아닙니다. (다른 iOS 버전에 대해 잘 모르겠습니다).

오류를 재현 하는 방법 :

  1. 게임을 엽니 다 (Safari 내부).
  2. 3-4 분 동안 실행합니다.
  3. 알림 센터를 아래로 내리면 모든 것이 미쳐 버립니다. iPhone 5C에서 오류를 재현하는 방법을 보여주는 YouTube 비디오
    추가했습니다 . 알림 센터에 문제가 처음 나타나는 것 같습니다 (상단에서 메뉴를 아래로 스 와이프 한 경우). 현재이 문제는 iOS 9.2.1 (13D15) 에서만 발생하는 것으로 보입니다 . 새로운 iOS 9.3 버전에서도 발생합니다.

    iPhone 5C

이 문제 를 해결 하려면 다음을 수행 해야합니다.

  1. 게임 탭이 열려있는 Safari 응용 프로그램을 닫습니다.
  2. 전화를 잠급니다. 잠금을 해제하면 모든 것이 정상으로 돌아갑니다.

게임 자체 에 대한 세부 정보 :

  1. 이 게임은 Mapbox 맵과 그 위에 일부 유닛 (마커)을 보여줍니다.
  2. Node.js 서버는 1 틱 / 초로 실행되며 각 틱 후에 업데이트 된 게임 상태가 Socket.io를 통해 브라우저로 전송됩니다.
  3. 브라우저가 게임 상태를 수신 할 때마다 그에 따라 마커를 업데이트합니다.
  4. * 확대 또는 축소하거나 마커를 선택하면 게임에서 마커를 업데이트 할 수도 있습니다.

EDIT2 : 예상대로 메모리 누수를 발견했습니다. 이 누수를 수정 한 후 ( undefined_icon 확인 ) 문제가 더 이상 발생하지 않습니다. 즉, 해당 라인 어딘가에서 Safari / iOS 버그가 트리거됩니다.

다음은 클러스터 된 각 유닛에 대해 정확히 각 틱이라고 부르는 것입니다 (숨겨지고 MarkerCluster 내에서 다른 유닛과 그룹화 됨).

    var $icon = $(marker._icon); // marker._icon is undefined because of the clustering

    $icon.html('');

    $icon.append($('<img class="markerIcon" src="' + options.iconUrl + '" />'));

    var iconX = 10;
    var iconY = -10;
    var iconOffset = 0;

    for(var v in this.icons) {
        this.icons[v].css('z-index', + $icon.css('z-index') + 1);
        this.icons[v].css('transform', 'translate3d(' + iconX + 'px,' 
                                + (iconY + iconOffset) + 'px,' + '0px)');
        iconOffset += 20;

        this.icons[v].appendTo($icon);
    }

    // Fire rate icons
    this.attackRateCircle = $('<div class="circle"></div>');
    this.attackRateCircle.circleProgress({
        value: 0,
        size: 16,
        fill: { color: "#b5deff" },
        emptyFill: 'rgba(0, 0, 0, 0.5)',
        startAngle:  -Math.PI / 2,
        thickness: 4,
        animation: false,
    });
    this.attackRateCircle.hide();

    // Create and display the healthbar
    this.healthBar = $('<div>').addClass('healthBar ');
    this.healthBar.css('z-index', $icon.css('z-index'));
    this.healthBarFill = $('<span class="fill">');
    this.healthBar.append(this.healthBarFill);

    $icon.append(this.healthBar);
    $icon.append(this.attackRateCircle);

그리고 이것은 icons배열입니다.

this.icons = {
    attack_order: $('<img src="img/attack.png" class="status_icon">'),
    attack: $('<img src="img/damage.png" class="status_icon icon_damage">'),
    hit: $('<img src="img/hit.png" class="status_icon icon_hit">'),
};

circleProgress이 라이브러리에서 호출 : https://github.com/kottenator/jquery-circle-progress

데모

예, 버그를 재현하는 jsFiddle을 만들 수있었습니다. https://jsfiddle.net/cte55cz7/14/ iPhone 5C의 Safari에서 열고 몇 분 정도 기다립니다. iPhone 6 및 iPad mini에서 페이지가 충돌합니다 (메모리 누수로 인해 예상대로).

HasteBin의 동일한 코드는 실행을 원하지 않는 사람을위한 것입니다.


2
추신 :에 질문을 게시하기 위해 비추천 된 후 SO에 게시되었습니다 SuperUser. 이 질문을 할 수있는 올바른 장소로 간주되기를 바랍니다.
XCS

2
@wottle 나는 내 iPhone 5C에서 테스트했고 다른 사람은 다른 iPhone에서 (다른 대륙에서 : D) 테스트했지만 그의 모델도 5C라고 생각합니다 (그가 실제로 그 인공물에 대해 말한 사람이었습니다). 내일 아이폰 6과 아이 패드 미니로 테스트 해 보겠습니다.
XCS

2
iPhone 6에서 재현되지 않습니다. CG의 버그 일 수 있습니다. 하드웨어 정보와 함께 모든 iOS 버전 정보를 게시 할 수 있습니까?
Fresheyeball

2
와! 그리고 난 ... 모바일 나쁜 윈도우 10의 화면 찢어 생각
BoltClock

6
A) 나는 화조차 내지 않았다. 그 놀라운. B) 이것이 실제로 익스플로잇으로 사용될 수 있는지 궁금합니다. 왜냐하면 당신은 분명히 할 수 없어야하는 메모리에 접근하고 있기 때문입니다. 그리고 C) 모든 것이 항상 왼쪽으로 기울어 져 있다는 것이 흥미 롭다고 생각합니다. 그것은 어떤 이유로 당신이 일부 텍스처의 피치 (일명 보폭)를 늘리거나 GPU의 피치 로직을 수정하고 있음을 나에게 제안합니다. 확실히 Safari / iOS / 펌웨어 버그입니다.
0x24a537r9

답변:


1

이 메모리 누수는 아마도 'WebKit의 JS Engine'이 작동하는 방식 때문일 것입니다. [safari webkit-javascript llvm]

나머지 RAM에 직접적인 영향을 미치는 가상 메모리 버퍼 오버플로처럼 보입니다 (사용자 인터페이스 그래픽 요소를 저장하기 위해 iOS에서도 공유되고 사용됨).

코드 조각과 관련하여 : "[...] jQuery 메모리 누수를 찾는 것은 쉽습니다. $ .cache의 크기를 확인하십시오. 크기가 너무 크면 검사하고 어떤 항목이 남아 있는지 확인하십시오. [...]"( http://javascript.info/tutorial/memory-leaks )

for 루프 와 관련이 있다고 예상하겠습니다 .

for(var v in this.icons) {
    this.icons[v].css('z-index', + $icon.css('z-index') + 1);
    this.icons[v].css('transform', 'translate3d(' + iconX + 'px,' 
                            + (iconY + iconOffset) + 'px,' + '0px)');
    iconOffset += 20;

    this.icons[v].appendTo($icon);
}

검사가 완료되었다고 가정하고 항목을 찾았다 고 가정하면 removeData ()를 사용 하여 데이터를 수동으로 정리 하거나 먼저 $ elem.detach () 를 사용한 다음 $ (elem) .remove ()를 입력 할 수 있습니다. setTimeout에서.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.