2014年11月4日火曜日

Android OutOfMemory (メモリリーク) の調査方法

Android メモリリークの調査方法のメモ


1.エミュレータでアプリケーションを起動

2.DDMSを起動して、注目するアプリケーションのパッケージのスレッドを選択し、UpdateHeapを選択する。

3.いろいろ操作、リークの可能性がある箇所がわかっている場合、その周辺を重点的に
 ちなみに、画面の向きを90度回転させるには、Ctrl + F11

4.アプリケーションを閉じる。アプリケーションが全面に無い状態にすること。

5.DDMS上でGCを実施する。

6. Dump HPROF Fileを実施し、hprofファイルを出力する。
hprofはJava標準のプロファイラ

7.hprof-convコマンドで標準hprofファイルを作成し、jhatで解析する。
・hprof-convはAndroid SDKに付属する。
・jhatはJavaSDKに付属する。

> hprof-conv jp.mixi.assignment.controller.adv2.hprof adv2.hprof

> jhat adv2.hprof

8.http://localhost:7000 にアクセスして、jhatの解析結果を確認する。

パッケージごとに解析できたクラスが表示される。
自分のアプリケーションのクラスを確認して、References to this object を探す。
References to this objectには、リンクが残り、メモリにインスタンスが配置されたままであることを示す。

ActivityがDestroyされた場合、GCで回収されるはずなので、リークしていると考えられる。

どこから参照されているかは excludes weak refs (外部弱参照)で確認する。
外部参照を見つけたら、参照を破棄するなどの対策を行う。

ブロードキャストレシーバーなど、リークのつくりやすい例で試すと良い。


2014年10月31日金曜日

Eclipse C++ 環境 OS X 10.9.5

Eclipseに慣れているので、Macでも入れておく。標準のC++を使用するまでの、パスの設定をメモしておく。他にライブラリを使うときは、随時追加をすること。

cmakeとgccをインストールしておく

$ brew install cmake

gccはxcodeのコマンドラインツールをインストールする。

Eclipseは最新のものインストールすれば良い。

CDTに以下のヘッダファイルとパスを設定する。

ヘッダファイルには以下を追加した。

/usr/include/c++/[バージョン番号]

MacOSのC++リンカーのコマンドに以下を追加する。

-stdlib=libstdc++

以上!

2014年10月29日水曜日

AndroidのViewとレイアウトについてメモ

AndroidのViewとレイアウトについてメモ


Androidの画面を構成するのは View である。

Viewには2つのタイプがあり、Widget と Layout と呼ばれる。

●Widget

  TextViewやButtonなどで、画面を操作したり、情報を表示する部品。

●Layout

  LinearLayoutやRelativeLayout、FrameLayoutなどで、画面の構成を決めるもの。


View を画面上のどこに、どのように配置するかをパラメータで指定する。
パラメータについて見ていこう。

ここから説明するパラメータをlaytou用xmlで使用する場合、基本プレフィックスとて「android:」が必要である。

●Viewの大きさを指定するパラメータ


  layout_height viewの高さ
  layout_width viewの横幅

  高さや横幅を指定するときの単位には、以下が使用出来る。

  ・絶対値を指定する

    dp(dip):density-independent pixels(密度非依存のピクセル)
     160dot/inch(dpi)の画面を基準とし、1dpiは160dpiの画面で1ピクセルと同義である。
     px = dp * (dpi / 160)
     つまり、画面の解像度(dpi)によって、(dpi/160)の比率で自動的に px を決定するため、
     複数の解像度端末に対応出来る。
    sp:scale-independent pixels(スケール非依存のピクセル)
     指定したサイズは解像度とユーザが設定したフォントのサイズに合わせて自動的にスケールされる。
     dpと似ているが、フォントサイズに依存する点で異なる。
    px:ピクセル単位
    たとえば、480px X 800pxの画面であれば、
    1pxは画面の1/480ということになる。
    Viewの幅や高さ、マージン、パディングはdpで指定し、文字サイズに関してだけspで指定することが多いようである。
    また、画面レイアウトファイルで「android:textsize」属性を指定しない場合(デフォルト)では、フォントサイズの単位にspが使用される。
    はじめは、480px×800pxを想定して作成し、その後他の解像度の端末で検証すると良い。
    googleの公式:http://developer.android.com/intl/ja/design/style/metrics-grids.html

  ・相対的に指定する

    match_parent(fill_parent:API Level8から非推奨):親のViewと同じサイズ
    wrap_content:コンテンツを表示するのに十分なサイズ

●Viewの余白を指定するパラメータ


  padding:Viewの内側の余白
  layout_margin:Viewの外側の余白

  paddingやlayout_marginは、上下左右を別々に指定することが可能である。

  padding、layout_marginの後ろに、Top(上)、Bottom(下)、Left(左)、Right(右)を指定するだけである。


●位置を指定するパラメータ

  Gravityを使用する。レイアウトとViewの関係を指定することが出来、UIのイメージをしながら構築する。

  gravity:内部の要素の位置を決める
  layout_gravity:自分の位置を決める


●レイアウト

  UIの構造を定義する。


  LinearLayout:Viewを直線的(線形)に並べることができる
    ・どの方向に並べるか
     orientation:horizontal(横、デフォルト) or vertical(縦)
    ・子要素の重み
     layout_weight:View配置の残りのスペースを埋める。指定しない場合、0が割り当てられる
     レイアウト中のViewは割り当てられた重み分だけ残りのスペースを埋めるように表示される。

  RelativeLayout:Viewを相対的に配置することができる

    以下のようなパラメータによってView同士の位置関係によって画面を構成できる。
    layout_above:指定したidのViewの上
    layout_alignBaseline:指定したidのViewのベースラインにあわせる
    layout_alignBottom:指定したidのViewの下端にあわせる
    layout_alignLeft:指定したidのViewの左端にあわせる
    layout_alignParentBottom:親となるViewの下端にあわせる
    layout_alignParentLeft:親となるViewの左端にあわせる
    layout_alignParentRight:親となるViewの右端にあわせる
    layout_alignParentTop:親となるViewの上端にあわせる
    layout_alignRight:指定したidのViewの右端にあわせる
    layout_alignTop:指定したidのViewの上端にあわせる
    layout_below:指定したidのViewの下
    layout_centerHorizontal:親となるViewの横方向の中央
    layout_centerInParent:親となるViewの中央
    layout_centerVertical:親となるViewの縦方向の中央
    layout_toLeftOf:指定したidのViewの左側
    layout_toRightOf:指定したidのViewの右側
  

  FrameLayout:Viewを重ねて配置する。

    FrammeLayoutのViewが、レイアウトファイルに記述された順番で配置される。

  ScrollView:画面にレイアウトが収まりきらなかった場合に、収まらない分をスクロールして表示する。

    子にもつルートとなるViewは1つでなければならない。つまり、ScrollViewに直接複数のTextViewを指定せず、TextViewをもつLinearLayoutを、ScrollViewに配置するなどである。


2014年10月22日水曜日

DeepLearningFramework Caffe Install MacOSX

DeepLearningのFramework CaffeをMacOS X 10.9.5 にインストールする。

ころころ変わるようなので、あくまで2014/10/21時点での方法である、悪しからず。

GPUを使用するため、はじめにCUDAをインストールする。

NVIDIA Cuda Driver
OSのバージョンに合わせて選択する。

NVIDIA Cuda

DriverのアップデートとCuda、サンプルが含まれる。

cuDNNを使うと速いよ、って書いてあるが残念ながら6.5ではまだMacOSに対応していない。

BLAS

Basic Linear Algebra Subprograms
数学的な計算を行うライブラリを入れる。
Caffeは3種類のライブラリに対応していて、どれを使っても良い。
MacOSの開発者ライブラリにもともと含まれる、ATLASを使用するので、作業無し。


Anaconda

機会学習に用いるpythonの科学計算ライブラリの構築に用いる。
pyenvを事前インストールしてから、Anacondaをインストール
> brew install pyenv
> pyenv install anaconda-2.0.1
> pyenv rehash
> sudo pyenv local anaconda-2.0.1
> sudo pyenv global anaconda-2.0.1

OpenCV

ご存知、画像処理ライブラリ。
> brew install opencv
> brew edit opencv
      -DPYTHON_LIBRARY=#{py_prefix}/lib/libpython2.7.dylib
      -DPYTHON_INCLUDE_DIR=#{py_prefix}/include/python2.7

The prerequisite home-brew formulae

homebredのformulaeの変更が必要なものがある。

以下のライブラリ

boost snappy leveldb protobuf gflags glog szip lmdb homebrew/science/opencv
それぞれ brew edit ... としても良いが、以下のコマンドでまとめてできる。
for x in snappy leveldb protobuf gflags glog szip boost boost-python lmdb homebrew/science/opencv; do brew edit $x; done
すべて、def install以下に修正を加える。
def install
      # ADD THE FOLLOWING:
      ENV.append "CXXFLAGS", "-stdlib=libstdc++"
      ENV.append "CFLAGS", "-stdlib=libstdc++"
      ENV.append "LDFLAGS", "-stdlib=libstdc++ -lstdc++"
      # The following is necessary because libtool likes to strip LDFLAGS:
      ENV["CXX"] = "/usr/bin/clang++ -stdlib=libstdc++"
ここで、本当はboostのバージョンを1.55にするべきだけど、手戻り的にやったのでここでの方法は試していない、ちなみに以下のように修正した。
boostのバージョンが1.55で無いとうまく動かないよ、という記述に気づいていなかった。
対処としては、以下のURLを参考に、caffe用の/usr/local/のbranch上でboostのformulaを書き換えて、再度brewでインストールした。
https://github.com/BVLC/caffe/issues/1193#issuecomment-57491906
上記のファイルのinstall部分を、再度libstdc++を使ってコンパイルするように書きなおしてから、アンインストール、インストールを実行。
> brew uninstall boost
> brew uninstall boost-python
brew install --build-from-source --fresh -vd boost boost-python 

formulaを書き換えたらあとはインストール。
for x in snappy leveldb gflags glog szip lmdv homebrew/science/opencv; do brew uninstall $x; brew install --build-from-source --fresh -vd $x; done
brew uninstall protobuf; brew install --build-from-source --with-python --fresh -vd protobuf
brew install --build-from-source --fresh -vd boost boost-python

Caffeブランチ

以下で、Caffe用のライブラリをブランチ管理し、他のパッケージに影響しないようにする。
cd /usr/local
git checkout -b caffe
git add .
git commit -m "Update Caffe dependencies to use libstdc++"
git checkout master
brew update
git rebase master caffe
# Resolve any merge conflicts here
git checkout caffe

Caffeのクローン 

> git clone https://github.com/BVLC/caffe.git
> cd caffe
> cp Makefile.config.example Makefile.config
Makefile.configを編集する。
cuda6以上を入れている場合は以下のようにコメントアウト
-gencode arch=compute_50,code=sm_50 \
-gencode arch=compute_50,code=compute_50
pythonインターフェースのパスPYTHON_INCLUDE, PYTHON_LIB を変更する。
# Anaconda Python distribution is quite popular. Include path:
PYTHON_INCLUDE := $(HOME)/.pyenv/versions/anaconda-2.0.1/include \
                  $(HOME)/.pyenv/versions/anaconda-2.0.1/include/python2.7 \
                  $(HOME)/.pyenv/versions/anaconda-2.0.1/lib/python2.7/site-packages/numpy/core/include
PYTHON_LIB := $(HOME)/.pyenv/versions/anaconda-2.0.1/lib


コンパイル&テスト

> make all
> make test
> make runtest

標準出力には大量の出力があるが、それぞれのパラメータの意味はよくわからない。
runtestの前に、ライブラリにパスが通っているか確認すること。
DYLD_FALLBACK_LIBRARY_PATHに対して、以下の値を設定する。
/usr/local/cuda/lib:$HOME/anaconda/lib:/usr/local/lib:/usr/lib

runtestは、以下のようにPASSしたことがわかる。
[==========] 838 tests from 169 test cases ran. (142854 ms total)
[  PASSED  ] 838 tests.

インストール完了!

2014年9月13日土曜日

新しいiTunesConnect(Aug 2014)にバイナリを上げたらWarning Build ~ does not contain the correct beta entitlement.

2014年の8月に、iTunesConnectが大きく変わった。

iTC上でのバイナリの管理方法が変わったこともあって、変更前に生成したバイナリだと以下のWarningが出ることがある。


Build ~ does not contain the correct beta entitlement. 

発生したら、App Store リリース用の Provisioning Profile を変更してビルドすれば良い。

2014年9月4日木曜日

tomcatのログローテート

logrotateコマンドを使用する方法


Amazon Linux、CentOS では、yum でインストール出来る。
Redhat系だったら導入は簡単ということ。他のディストリビューションは手元に無いので確認していない。

以下に設定ファイルを作成する。

/etc/logrotate.d

ファイルの名前で、logrorateを使っているアプリケーションがわかる。

ここでは、「/etc/logrotate.d/tomcat」とする。root で作業。

# vi /etc/logrotate.d/tomcat

# logrotate file for Tomcat
/opt/tomcat/logs/catalina.out {
  missingok
  copytruncate
  daily
  dateext
  rotate 60
}


オプションの整理



  • missingok:ログファイルが無くてもエラーを出さない
  • copytruncate:
  • daily:日でローテート
  • dateext:ファイル名末尾に日付をつける
  • rotate:残す世代数
  • compress:最新世代以外は圧縮
  • size:最大サイズを指定。最大になるとローテート


/etcc/cron.daily 配下のファイル logrotate がある。つまり、logrotateはcronによって毎日走る。

実行スクリプトがどこにあるかというと、logrotate.d にすべてのスクリプトが含まれる。

include /etc/logrotate.d



logrotateの強制実行


# logrotate -f /etc/logrotate.d/tomcat


cron.dailyの強制実行


# anacon -f

上記で、少なくとも logrotate と cron による実行確認可能。

サーバに設定して、動作確認すればOK。


accesslogの設定



catalina.outだけでなく、accessログも logrotate でローテートする場合は、tomcatが自動でローテートしないように以下の設定を行う。

        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="access_log." suffix=".txt" ←★ファイル名は access_log.txt に固定される
               rotatable="false" ←★ 自動ローテートをOFF
               pattern='%h %l %u %t "%r" %s %b %D "%{Referer}i" "%{User-Agent}i"' />

その後、tomcatのローテート設定にファイルを追加する。

# logrotate file for Tomcat
/opt/tomcat/logs/catalina.out
/opt/tomcat/logs/access_log.txt
{
  missingok
  copytruncate
  daily
  dateext
  rotate 60
}

2014年9月3日水曜日

JNIの関数の戻り値を文字列にする時の簡単な注意事項

JNI でコーディングする間が開いたので、コンパイルに失敗してjstringで文字列を作成する関数なんだっけ、で数分を失ったのでメモ。

以下の関数で jstring を生成する。

jstring strj = env->NewStringUTF("debug");

既知なことだと思うが、envは引数JNIEnvを指す。