web-dev-qa-db-ja.com

IOS7でGoogleマップがクラッシュする

ハイブリッドアプリを開発しており、アプリケーションでgoogle map APIを使用しています。マップに2000個のデータマーカーをロードしようとすると、クラッシュしました。 IOS6、IOS5ではマップはクラッシュしません。 IOS7でのみ発生しています。 ios7アプリケーションに対して行われたメモリ関連の変更はありますか。

42
user2771801

前述したように、iOS7はメモリ使用に関してより厳格です。この動作はChromeなどの他のブラウザーで発生するため、アプリのメモリ使用量が上限に達すると、クラッシュが発生します。

Gmaps JavaScript APIとjQueryのみを使用して2つのテストケースを分離しました。

100個のマーカーを使用したテスト:すべて問題ありません

http://jsfiddle.net/edfFq/6/embedded/result

3000マーカーを使用したテスト:クラッシュが発生します

http://jsfiddle.net/edfFq/7/embedded/result/

$(document).ready(function () {
    var map;
    var centerPosition = new google.maps.LatLng(40.747688, -74.004142);


    var options = {
        zoom: 2,
        center: centerPosition,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    map = new google.maps.Map($('#map')[0], options);


    for (var i=0;i<2800;i++){        
      var position = new google.maps.LatLng(40*Math.random(),-74*Math.random());
      var marker = new google.maps.Marker({
            position: position,
            map: map           
        });
    }
});

マップでラベル、カスタムアイコン、クラスターを使用している場合、少ないマーカー数でクラッシュする可能性があります。

13
nachoorme

Googleマップで同様の問題が発生したため、最小限のテストケースを分離しようとしました。これがおそらくより一般的なメモリ管理の問題かどうかを確認したかったのです。

配列にランダムデータを保存するだけのこのコードは、iPad Mini、16GBでIOS 7でSafariをクラッシュさせます。

function randomString(length, chars) {
    var result = '';
    for (var i = length; i > 0; --i) result += chars[Math.round(Math.random() * (chars.length - 1))];
    return result;
}

var arr = []
for (var i=0;i<5000;i++) {
    // one character is two bytes in JavaScript, so 512 chars is 1Kb:
    o = randomString(512, '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ');
    arr.Push(o);
}

http://vici.org/memtest.html に進むことで、独自のブラウザでこのテストを試すことができます。そのページのスクリプトは、1MBずつ50MBのメモリを要求しようとします。スクリプトには実行中のカウンターが表示されるため、ブラウザーのパフォーマンスとクラッシュした場合(クラッシュした場合)を確認できます。スクリプトは、いくつかの結論を導き出すことができるように、各IP /ユーザーエージェントの組み合わせの結果をデータベースに保存します。

平均して、IOS 6(n = 12)は、スクリプトが約12Mbを要求できるようにします。IOS 7(n = 47)は、スクリプトが約15 Mb。これらは厳しい制限ではありません。両方のセットで標準偏差は非常に高く、12 Mbでした。Xcodeエミュレーターでは、Safariはまったくクラッシュしません(おそらく、より多くのRAMにアクセスできるため、50 Mbがいっぱいです)。

そのため、この問題はIOS 7によってSafariのメモリが少なくなることによって引き起こされたものではないと結論付けることができます。問題は、フィリップクーンが示唆したように、特定のケースでは?-Safari IOS 6.よりも多くのメモリを消費します。6。原因についての手がかりは https://discussions.Apple.com/message/23837361#23837361 にあります。 = 200 divのページと次のCSS

div {
  -webkit-backface-visibility: hidden;
}

サファリをクラッシュさせます。

Leafletライブラリを使用すると、マップの問題を回避できるようです( https://code.google.com/p/gmaps-api-issues/issues/detail?id= および https ://github.com/Leaflet/Leaflet/Leull/pull/2149 )ただし、リーフレットはcssではなくjavascriptレベルでの変更によるメモリ不足のクラッシュを回避しました。リーフレットは、次のようなステートメントを回避します

context = this

これは、Safariが未使用のオブジェクトをクリーンアップしないことを示唆しています。 AppleがSafariを修正しない限り、GoogleはLeafletの人たちが行ったことと同様の変更を行うことができるでしょうか?

その間、AppleはリリースIOS7.1を持っています。これはクラッシュを完全には解決しませんが、確かに頻繁に発生します。

8
Tuxzone

IOS7には多くのマーカーでクラッシュするWebアプリケーションがあります。そこで、iPadが使用するメモリを詳しく調べました。

iOS7を搭載したiPad mini(およびiPad3):

メモリ使用量はますます高くなり、ブラウザがクラッシュする300-400MBの間です。

iOS6を搭載したiPad

メモリ使用量は約200MBで、すべて問題ありません。

iOS5を搭載したiPad 1

メモリ使用量は約100MBのみで、すべて問題ありません。

結論

これは[〜#〜] not [〜#〜]単なるメモリ制限です。これは間違いなくiOSサファリの大きなバグです!そして今まで(iOS 7.0.3)これは修正されていません。

7
Philipp Kühn

良いニュースです!アプリフレームワークをGoogleからリーフレットに切り替えたところ、クラッシュせずに美しく機能し、デバッグを確認し、非常に高いメモリを実行しましたが、クラッシュすることはありませんでした。 Leafletをまだ使用していない場合は、iOS 7で完全に機能します

4
Jason G

このアプリケーションは、上記のユーザーと同じように動作しました。 iOS 7より前はすべて正常に機能していましたが、その後クラッシュしました。問題は確かにメモリの問題のようです。デバイスのクラッシュレポートログを確認することで確認できます。

私たちのアプリケーションはクライアントにとって不可欠であったため、Appleからの修正を待つことはできませんでした。私たちの場合、修正には3つの特定の戦略が関係していました。

  1. Javascriptコードの最適化。私たちのアプリケーションは非常に迅速に開発され、大規模なコード計画なしでプロトタイプから実用的なシステムに変わりました。私たちのシステムでは、コードを最適化することで大幅なメモリゲインを実現できました。これは、未使用の変数を削除することを意味しました。データベースからの応答としてすべてのマーカーを予備の配列に保存する場合があります。すべてが正常にロードされたら、これらの古い配列と未使用の変数を削除します。さらに、含まれるライブラリの制限を検討し、一般的なJavascript/jQueryの最適化のベストプラクティスを採用します。

  2. 空の情報ウィンドウ。次のメモリ節約戦略は、各マーカーの情報ウィンドウ画面にデータをプリロードしないことから来ました。一意のIDを持つ空のdivを除き、各情報ウィンドウをむき出しにしました。これは、Ajaxを介してクリックすると非同期に読み込まれます。不要な情報ウィンドウデータをすべて取り出すと、何千ものマーカーによる節約はかなり大きくなりました。約10,000個のマーカーをロードしていました。プリロード時間とAjaxロード時間の差は無視できるため、ユーザーエクスペリエンスは大きな影響を受けませんでした。

  3. 最大の違い、そしておそらくiOS 7のメモリリークがどこにあるのかについての手がかりは、画面に一度に表示されるマーカーの数を単に減らすことから来ました。各アプリケーションは異なりますが、結果を500マーカー以下に下げると、クラッシュすることなく安定したシステムになることがわかりました。私たちの戦略は、ユーザーの行動に基づいて、表示されているマーカーの配列を単にロードしてクリアすることでした。たとえば、ユーザーの特定のフィルター選択により500を超えるマーカーが生成された場合、データベースからの結果を単純に制限しました。視覚的には、結果セットは依然として大きく見えますが、ユーザーエクスペリエンスの観点から、何千ものマーカーを見てもそれほど違いはありません。どちらの場合でも、ユーザーは結果をフィルター処理して絞り込み、管理可能な結果を​​得る必要があります。この場合、ユーザーは制限に気付かないでしょう。

これでうまくいきました!これで、アプリケーションはクラッシュしなくなりました。時間の長さ(フラストレーションは言うまでもありません!)を考えると、この問題が私を引き起こしました。願わくば、これらの戦略があなたのアプリケーションをバックアップして動作させるための出発点になることを願っています。もう少し具体的なものが必要な場合は、お気軽にご連絡ください。幸運を!

3
Andrew

IOS 7.1で修正されるようです

昨日iOS 7.0.6で、私のマップは3,000を超えるマーカーでMobile Safariをクラッシュさせました。今日、iPadをアップグレードした後、15,000を超えるマーカーを含むマップをMobile Safariに読み込むことができます。

0
Skye

ちょっと...私も同様の問題に直面していました。だから、私はこれを試しました:

View Controllerとカスタムプラグインの「didReceiveMemoryWarning」メソッドでアプリケーションキャッシュをクリアし、CDVPluginクラスの「onMemoryWarning」メソッドでプロパティと変数をNILに設定しました。そして、このアプローチは私のために仕事をしてくれました。今のところクラッシュしていません。お役に立てれば。

0
anshul

多数のマーカーを扱っている場合は、 MarkerClusterer を使用してみてください。これにより、同時マーカーの数が大幅に減少し、今回のケースではクラッシュを防止しました。

IOS7のメモリキャップは5Mb(バッテリー寿命が長い)で、以前は50Mb程度でしたと思います。上限はOSによって制限されているため、Chrome、Safari、またはその他のブラウザを使用しているかどうかは関係ないため、超過するとクラッシュします。

sQLからの受信データ制限を20にテストしました。これは、iPhone(パッド)上のすべてのブラウザーで機能します。

0
Stefan George

私は同じ問題を抱えていて、いくつかのことを試しました。マーカーを設定するとアニメーションが無効になり(一度に約30個追加されました)、もうクラッシュしなくなったようです。お役に立てば幸いです。

0
user2816463

Googleマップのラベルにも同じ問題があります。地図のズームインアプリがクラッシュするとき。これは、IOS 7.へのアップグレード後に発生し始めました。「ドラッグ」や「アイドル」などのイベントでラベルの削除や追加などのさまざまなオプションを試しています。誰かがこの問題をより良く修正してくれることを願っています。

    google.maps.event.addListener(Map.gmap, 'drag', function () {
            $('.arrowSite_box').remove(); // remove labels
    });

    google.maps.event.addListener(Map.gmap, 'idle', function () {
        loadMarkers(results); // add labels
    });
0
Jan_M