나는 제목이 그다지 설명 적이 지 않다는 것을 알고 있지만 여기에 이야기가 있습니다. 주로 JavaScript와 Mapbox 라이브러리를 사용하여 브라우저 게임을 개발하고 있습니다.
데스크톱, Android 및 iOS에서 모든 것이 잘 작동하지만 iOS에서는 한 가지 문제가 나타납니다. 게임을 몇 분 동안 실행 한 후 갑자기 전화에 그래픽 아티팩트가 나타나고 대부분의 텍스트가 뒤섞여 표시됩니다.
내 질문 은 : 내 코드에서 정확히 무엇이 이것을 일으킬 수 있습니까? 메모리 누수? ( LE : 실제로 메모리 누수로 밝혀졌습니다.)
진짜 질문 은 어떻게하면 단순히 웹 페이지를 검색하는 것으로 전체 전화기를 거의 브릭 킹 할 수 있다는 것입니다. 사파리가 이것을 막아야하지 않나요? 아니면 적어도 iOS 는요?
이 문제는 다른 iPhone 장치에서 재현 될 수 있으므로이 특정 장치의 문제가 아닙니다. (다른 iOS 버전에 대해 잘 모르겠습니다).
오류를 재현 하는 방법 :
- 게임을 엽니 다 (Safari 내부).
- 3-4 분 동안 실행합니다.
- 알림 센터를 아래로 내리면 모든 것이 미쳐 버립니다. iPhone 5C에서 오류를 재현하는 방법을 보여주는 YouTube 비디오 를
추가했습니다 .
알림 센터에 문제가 처음 나타나는 것 같습니다 (상단에서 메뉴를 아래로 스 와이프 한 경우).
현재이 문제는 iOS 9.2.1 (13D15) 에서만 발생하는 것으로 보입니다 . 새로운 iOS 9.3 버전에서도 발생합니다.iPhone 5C
이 문제 를 해결 하려면 다음을 수행 해야합니다.
- 게임 탭이 열려있는 Safari 응용 프로그램을 닫습니다.
- 전화를 잠급니다. 잠금을 해제하면 모든 것이 정상으로 돌아갑니다.
게임 자체 에 대한 세부 정보 :
- 이 게임은 Mapbox 맵과 그 위에 일부 유닛 (마커)을 보여줍니다.
- Node.js 서버는 1 틱 / 초로 실행되며 각 틱 후에 업데이트 된 게임 상태가 Socket.io를 통해 브라우저로 전송됩니다.
- 브라우저가 게임 상태를 수신 할 때마다 그에 따라 마커를 업데이트합니다.
- * 확대 또는 축소하거나 마커를 선택하면 게임에서 마커를 업데이트 할 수도 있습니다.
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에서 페이지가 충돌합니다 (메모리 누수로 인해 예상대로).
답변
이 메모리 누수는 아마도 ‘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에서.