2015-12-20 11 views
6

私はリアクションネイティブ0.17でモバイルプールゲームを構築しようとしていますが、ガベージコレクションに関する問題が発生しています。今私は、画面の周りにバウンスすると同時にレンダリングされている10の円があります。しかし、アプリケーションのメモリ消費量は時間とともに増加しており、この問題に対処する方法はわかりません。ネイティブメモリリークに反応するアニメーションの問題

以前のバージョンではReact Nativeの問題だったようですが、ここでグラフに示すように時間が経つにつれて通知がメモリに落ちますが、はるかに大きなアプリケーションでは、これが問題になる可能性があります。他の誰かが似たような問題を抱えていたのですか?

関連コードはここにあり、何か助けに感謝します。ありがとうございました!

VARテスト= React.createClass({

getInitialState: function() { 
    var circs = []; 
    for (var i = 0; i < startCount; i++) { 
     circs.push({ 
      id: i, 
      x: 0, 
      y: 0, 
      vx: 2 + Math.random() * 2, 
      vy: 2 + Math.random() * 2, 
      dx: 0, 
      dy: 0, 
      cOb: new Animated.ValueXY({x: 0, y: 0}), 
     }); 
    } 

    return { 
     circles: circs, 
     stop: 1 
    }; 
}, 
stopCircle: function() { 
    this.state.stop = -1 * this.state.stop; 
    this.setState(this.state); 
}, 
componentDidMount: function() { 
    this.animateCircles(); 
}, 
animateCircles: function() { 
    this.triggerAnimation(this.animateCircles); 
}, 
triggerAnimation: function(ani) { 
    for (var i = 0; i < this.state.circles.length; i++) { 
      var cCircle = this.state.circles[i]; 
      if (cCircle.x * cCircle.x + cCircle.y * cCircle.y > DIST_TO_EDGE * DIST_TO_EDGE) { 
       var prevX = cCircle.x - cCircle.vx; 
       var prevY = cCircle.y - cCircle.vy; 
       var exitX = (1.5 * prevX + .5 * cCircle.x)/2; 
       var exitY = (1.5 * prevY + .5 * cCircle.y)/2; 
       cCircle.x = prevX; 
       cCircle.y = prevY; 

       var exitRad = Math.sqrt(exitX * exitX + exitY * exitY); 
       exitX = exitX * DIST_TO_EDGE/exitRad; 
       exitY = exitY * DIST_TO_EDGE/exitRad; 

       var twiceProjFactor = 2 * (exitX * cCircle.vx + exitY * cCircle.vy)/(DIST_TO_EDGE * DIST_TO_EDGE); 
       cCircle.vx = cCircle.vx - twiceProjFactor * exitX; 
       cCircle.vy = cCircle.vy - twiceProjFactor * exitY; 
       break; 
      } 
    } 
    if (this.state.stop == 1) { 
     for (var k = 0; k < this.state.circles.length; k++) { 
      this.state.circles[k].x += this.state.circles[k].vx; 
      this.state.circles[k].y += this.state.circles[k].vy; 
     } 
    } 
    this.setState(this.state); 
    var animateC = []; 
    for (var i = 0; i < this.state.circles.length; i++) { 
     var currCirc = this.state.circles[i]; 
     animateC.push(
      Animated.timing(currCirc.cOb, { 
       ...TIMING_CONFIG, 
       toValue: {x: currCirc.x, y: currCirc.y} 
     })); 
    } 
    Animated.parallel(
     animateC 
    ).start(ani); 
}, 
getStyle: function(which) { 
    return [ 
     styles.circle, 
     {transform: this.state.circles[which].cOb.getTranslateTransform()} 
    ]; 
}, 
render: function() { 
    return (
     <View style={styles.container}> 
      <View style={styles.edge}> 
      </View> 
      { 
       this.state.circles.map(function(c, i) { 
        return (
         <TouchableWithoutFeedback key={i} onPress={this.stopCircle}> 
          <Animated.View style={this.getStyle(i)} /> 
         </TouchableWithoutFeedback> 
        ); 
       }, this) 
      } 
     </View> 
    ); 
}, 

あなた自身のためのアプリケーションを実行したい場合は、完全なアプリケーションがhttps://github.com/heliumsoule/React-Native-Poolで見つけることができます。

が再びありがとう。

+0

this.setState(this.state);それは何ですか?私は前にそれに遭遇したことはなかった。 – Hasen

答えて

0

ます単純な数値とオブジェクトの両方の一時変数がたくさんありますが、これが頻繁にヒットするのか、アニメーションが複数のフレームにまたがるのかは完全にはわかりません。すべてのフレームであれば、割り当てのトン。時間がたつにつれて蓄積し、ガベージコレクタがトリガされると少し休止します。

割り当ての数を減らすために、一時変数をインスタンス変数に変換して再利用することができます。

私はそこに任意の最適化があるかどうかを知るためにアニメーションAPIと十分に熟知していないよ...

+0

James、私はあなたの提案を試み、変数を再割り当てするのではなくインスタンス変数を作成しましたが、メモリ使用量はまだまだ増加しています。 – user1844067

+0

少し助けてくれてうれしい。あなたが割り当てをしている限り、解放される前にメモリがゆっくりと這い上がると期待するべきです。これは現代のJS VMが動作する方法です。メモリのデバッグに慣れ親しむ時間があるかもしれません。アプリが起動したら、スナップショットをいくつか撮ってください。あなたはそれらを比較して、何が拡大しているのかを見ることができます。 – James

0

あなたは、両方が自分の条件にガベージコレクションを実行する2台の仮想マシンを持っています。 JVMとJavaScript。

この記事はあなたを助けるかもしれない:

http://moduscreate.com/dynamic-memory-and-v8-with-javascript/

をまた、私はあなたができる限り多くのコードをコメントアウトし、メモリへの影響を参照してください示唆しています。その後、一度に少しコメントして、メモリ消費が最も急速に増加するコードを見てください。

+0

マイケル、あなたの記事をありがとう。 JavaScriptがReact Nativeフレームワークでレンダリングされているため、2つのVMがあるかどうかはわかりません。主メモリの消費量は、呼び出し間の時間を指定するTIMING_CONFIGごとに呼び出されるtriggerAnimationメソッドを使用していることがわかります。しかし、私はジェームズの提案の後にコードをさらに最適化する方法を知らない。 – user1844067

+0

私はアンドロイドのエキスパートではありませんが、React NativeフレームワークはJavaであり、React Nativeコードを実行するために使用されるJSエンジンはV8です。あなたのアプリはJavaScriptからJavaScriptを呼び出しています。逆もまた同様です。 非常に長い時間プログラムを実行させるとどうなりますか?JavaとV8の両方は、デバイスのメモリが不足しているか、プロセスがその制限を使用しているまでガベージコレクションの一部を延期する可能性があります。 –

関連する問題