2016-03-14 16 views
7

アンドロイドのQt 5.5でQNetworkAccessManagerを使用する際に問題があります。 http GETを介して単純な小さなグラフィックファイルをダウンロードすると、その間にガベージコレクションの呼び出しが多く発生し、UIのロックアップが発生します。後続のGETは、これらのGCコールがなくても問題なく動作します。コードは以下の通りである:QNetworkAccessManager - 最初にGET非常に遅い

void DownloadManager::downloadFile(QUrl fromUrl, QString toFilePath) { 

    _currentFilePath = toFilePath; 

    QNetworkRequest request; 
    request.setUrl(fromUrl); 

    qDebug() << "before"; 

    _currentReply = _mgr.get(request); 

    qDebug() << "after"; 

    connect(_currentReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(downloadError(QNetworkReply::NetworkError))); 
    connect(_currentReply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(downloadProgress(qint64,qint64))); 
    connect(_currentReply, SIGNAL(finished()), this, SLOT(downloadFinished())); 

} 

DownloadManagerはget要求に関連する特別な機能を使用せずにカスタムQObjectの派生クラスです。 _mgrは、DownloadManagers cTorの間に割り当てられるQNetworkAccessManagerオブジェクトです。

ご覧のとおり、これはget requestの教科書の例に過ぎません。そして私が言ったように、それは大部分のために働く。最初のget要求は次のように終わる:

D/ .../downloadmanager.cpp:61 (void DownloadManager::downloadFile(QUrl, QString)): before 
D/dalvikvm(13298): GC_CONCURRENT freed 2290K, 25% free 10911K/14407K, paused 2ms+3ms, total 29ms 
D/dalvikvm(13298): GC_CONCURRENT freed 501K, 25% free 10884K/14407K, paused 13ms+2ms, total 35ms 
D/dalvikvm(13298): GC_CONCURRENT freed 524K, 25% free 10892K/14407K, paused 12ms+3ms, total 36ms 
D/dalvikvm(13298): WAIT_FOR_CONCURRENT_GC blocked 6ms 
D/dalvikvm(13298): GC_CONCURRENT freed 537K, 25% free 10887K/14407K, paused 2ms+9ms, total 32ms 
D/dalvikvm(13298): WAIT_FOR_CONCURRENT_GC blocked 14ms 
D/dalvikvm(13298): GC_CONCURRENT freed 840K, 25% free 10899K/14407K, paused 12ms+3ms, total 38ms 
D/dalvikvm(13298): WAIT_FOR_CONCURRENT_GC blocked 11ms 
D/dalvikvm(13298): GC_CONCURRENT freed 1294K, 25% free 10901K/14407K, paused 2ms+2ms, total 27ms 
D/dalvikvm(13298): WAIT_FOR_CONCURRENT_GC blocked 11ms 
D/dalvikvm(13298): GC_CONCURRENT freed 1187K, 22% free 11330K/14407K, paused 2ms+2ms, total 30ms 
D/dalvikvm(13298): WAIT_FOR_CONCURRENT_GC blocked 15ms 
D/dalvikvm(13298): GC_CONCURRENT freed 1459K, 19% free 11919K/14535K, paused 13ms+4ms, total 64ms 
D/dalvikvm(13298): WAIT_FOR_CONCURRENT_GC blocked 18ms 
D/ .../downloadmanager.cpp:65 (void DownloadManager::downloadFile(QUrl, QString)): after 

私は単に多くのGCが発生することに原因を理解していない - それはアウト動作するようにすべてのための完全に1と1.5秒程度かかり(のためにまた、非同期でUIをロックしないようにしてください)。

追加情報:

  • それは、常にこれをトリガーする唯一の最初のダウンロードです。正確に同じファイルであっても、その後のダウンロードは完全に動作します

  • 正確な名前で正確な場所にファイルがあるかどうかは関係ありません。ファイルをダウンロードして削除し、アプリケーションに戻って再ダウンロードすると、同じ結果が得られます。最初の取得は遅く、GCがあり、2つ目は完全にうまく動作します。

  • シングルトンC++オブジェクトがDownloadManager :: downloadFileを呼び出す原因となるすべてのQMLファイルを呼び出します。

  • QML UI以外は、アプリケーション内で実行中のものはありません。重いデータ交換も、他のスレッドへのバックグラウンドのロードも、何もしません。

これを解決するための参考に感謝します。

+0

'QNetworkAccessManager'はネットワーク要求を処理する独自のイベントループを持つワーカースレッドを生成します。おそらくそのイベントループを開始するとJavaに多くの呼び出しが行われますか? –

答えて

1

私はAndroidで試していませんでしたが、Windowsでも同じ問題がありました。これらは同じ症状であるため、同じ理由が考えられます。これは、最初のget()呼び出しでいくつかの共有ライブラリが遅延ロードされているためです。これは、暗号化された接続を使用する場合に特に当てはまります。私の場合は、最初のget()呼び出しで19のDLLがロードされていることがVisual Studioでわかります。

対処方法の1つは、暗号化された接続(HTTPSなど)を使用しているかどうかによって、connectToHostまたはconnectToHostEncryptedを使用してサーバーに事前接続することです。私はアプリケーションの起動時にそれを呼び出していますが、いつでもUIがアイドル状態であれば問題ありません。その後、ライブラリーがロードされ、接続が確立されているため、後続のget()呼び出しのパフォーマンスはすべて同じです(最初のものを含む)。私はに接続すると、サーバがライブラリをロードすると仮定しています。

一般的なエラーの詳細については、https://forum.qt.io/topic/65201/qnetworkaccessmanager-first-get-very-slow/14を参照してください(Androidに限定されません)。

関連する問題