Allowed memory size of 8388608 bytes exhausted

portupgrade 利用中に以下のエラーに遭遇。

# portinstall devel/pear
… (中略) ..
Fatal error: Allowed memory size of 8388608 bytes exhausted (tried to allocate 56 bytes) in /tmp/gopeypYZxF/PEAR/Registry.php on line 1006
Allowed memory size of 8388608 bytes exhausted (tried to allocate 5 bytes)
 *** Error code 1
 
Stop in /usr/ports/devel/pear.
 *** Error code 1
… (以下略)..

portinstall 中のことで一瞬何かと思いましたが、PHP 周りで 8388608bytes = 8M 制限といえば、php.ini の次の設定ですね。

memory_limit = 8M ; Maximum amount of memory a script may consume (8MB)

これを、一時的に 16M とかしたら問題なくインストールできました。

C#.NET と MVC(PAC)

件名:PACパターンにおいて、Formクラスはコントロール層なのか?
自動生成の Form だと、MVC の V+C な動作をしていますね。
結論としては、ここの流れどおり、コントローラを別に作って、そっちをエントリポイントにするのがベターじゃないかなと思います。
 
2006-02-08 追記:
よく使われる Application.Run(Form) だと、せっかく Main() メソッドを分離してもイベントハンドラの段階で V+C な形になってしまうので、ApplicationContext インターフェイスを実装してこれを Application.Run(ApplicationContext) に渡してやると、コントローラとビューの分離がよりスマートにできる。
 
2007-04-10 追記:
ApplicationContext を利用した場合の実装例はこんな感じになります。

using System;
using System.Windows.Forms;
 
class Controller : ApplicationContext{
    // MVC の view レイヤ( Controller との接合部のみを IView として interface にしてもよい)
    private Form1 view;
 
    // コンストラクタ
    internal Controller(){
        view = new Form1();

// フォームが閉じられた時にアプリケーションを終了させるためのイベントハンドラを追加。
view.Dispose += new EventHandler( delegate (object sender, EventArgs e){
Dispose();
Application.Exit();
});
// フォームを表示
view.Show();
    }
}

あとはこれを Program.cs などエントリポイント( static void Main(string[]) 関数)の

Application.Run(new Form1);

などとなっている箇所を

Application.Run(new Controller());

のようにすれば、直接 Form を呼び出す実装ではなく ApplicationContext を介した実装になります。
 
参考:
.NET TIPS – VB.NETでアプリケーション起動時に実行されるフォームを変更するには?(@IT)
VS.NET でのエントリポイントの設定の仕方について書かれています。
Application.Runメソッド(ApplicationContext) (MSDN -> .NET Framework-> リファレンス -> クラスライブラリ -> System.Windows.Forms -> Application クラス -> メソッド -> Run メソッド)
リンク先のサンプルの動作には次の宣言が必要。また、MyForm1, MyForm2 というフォームクラスを用意する必要がある。

using System;
using System.Windows.Forms;
using System.Drawing;
using System.IO;
using System.ComponentModel;
using System.Text;

C# で Java の final と同等の制限をかける

Java プログラマが C# を学ぶ際のメモ。final については探しても見当たらなかったので書いておきます。

定数・フィールドのfinal

定数に対しては const 識別子, コンストラクタ値を設定する書き込み禁止フィールドについては readonly 識別子を使います。

class Foo {
    private const int NUM_MAX = 65535; // 定数値。コンストラクタでの遅延代入が不可。
    private readonly int _id; // 書き込み禁止値。コンストラクタで遅延代入が可能。

<pre><code>public Foo(int id){
    _id = id;
}
</code></pre>

}

メソッド中で、遅延代入をする方法はなさそうです。

public doSomething(){
    readonly int j = 1; // これはエラー。readonly はフィールドでのみ可能。
    const int N;
    N = 10; // これもエラー。const は宣言と同時に代入しなければならない。
}

同様に、引数の final (引数の変数への再代入禁止)を C# で利用することはできません。

public void doSomeThing2(const int number); // const は引数には適用不可

クラスのfinal

クラスに対しては、sealed 識別子が同等の効果をもちます。

sealed class FinalClass{ /* … */ }

メソッドのfinal

Java におけるメソッドの宣言に対しての final は、C# ではデフォルトの実装のため、ポリモーフィズムについては C# のほうが Java より制限的といえます。

final でない(オーバーライド可能な)メソッドを定義するには、親で virtual 識別子をつけて宣言し、かつ子で override 識別子で明示してオーバーライドします。

override 識別子をつけている場合、さらにその子クラスでも再帰的にオーバーライドが可能です。オーバーライド可能なメソッドに対して「オーバーライドした上で子には禁止する」という動作を実装する場合は、クラスと同様に sealed 識別子を利用します。

class Parent {
    public virtual void Greet(){ // オーバーライド可能
        Console.WriteLine(“Hello”);
    }
    public void StandUp(){ // オーバーライド禁止。オーバーライドしようとするとコンパイルエラー
        // …
    }
}

class Child : Parent {
    public override void Greet(){ // オーバーライド。明示しないとコンパイルエラー
        Console.WriteLine(“Hi!!”);
    }
}

class GrandChild : Child {
    public sealed override void Greet(){ // オーバーライド。ただし、このクラスの子にはオーバーライドを許さない。
    }
}

参考:

VS.NET でソースコードを自動フォーマットする

ソースコードの自動フォーマット(Eclipse では Alt-Shift-F )を VisualStudio.NET で行うには次のようにします。

Ctrl-A, Ctrl-X, Ctrl-V

全て選択してカット&ペーストしてるだけだったりします。
ソースコードの一部分だけフォーマットしたい場合は、同様に該当箇所をカット&ペーストで可能です。
 
参考:
.NET TIPS ソース・コードのインデントを手軽に整えるには?

databases/mysql41-* から databases/mysql50-* へ移行

MySQL4.1 を使っていたのだが、MySQL5.0 がリリースされて久しいので置き換えました。
データベースの中身をダンプしてから置き換えて、ダンプから復元。

$ # あとで復元するためにデータをダンプ
$ mysqldump -AicFxp -u root –create-options > mysql.dump
$ su
# # 4.1 の停止処理
# /usr/local/etc/rc.d/mysql-server.sh stop
# mv /var/db/mysql{,_old}; mkdir /var/db/mysql # 一応退避。終われば古いものは不要になります。
# # 4.1 -> 5.0 へのバージョンアップ
# portupgrade -o databases/mysql50-client “mysql-client-4.1.16_1”
# portupgrade -o databases/mysql50-script “mysql-script-4.1.16”
# portupgrade -o databases/mysql50-server “mysql-server-4.1.16”
# portupgrade -fo databases/p5-DBD-mysql50 p5-DBD-mysql41-3.0002
# pkgdb -F # 念のため依存関係確認。
 
# # DB の初期化
# mysql_install_db –log-bin=hostname-bin # hostname-bin のところは任意の名前。
# # サーバを起動してここで復元。
# /usr/local/etc/rc.d/mysql-server.sh start
# mysql < mysql.dump # 復元
# /usr/local/etc/rc.d/mysql-server.sh restart # 変更の適用

参考:
MySQL 5.0 で一挙に増加 さまざまな特徴を持つストレージエンジン(日経BP ITPro)
 直接関係ないけど、5.0 の新機能について書いてあります。

利用可能な DNS サーバを調べる

nslookup コマンドを使うと、任意のISP(任意のネットワーク)が利用しているDNSサーバIPアドレスを調べることが可能です。
 
既に DNS が使える環境で、
nslookup を使い、ISP のホスト名についてネームサーバの解決をすることで調べます。

$ nslookup
Default Server: XXX.XXX.ne.jp
Address: XXX.XXX.XXX.XXX
 > set q=ns # ← set q=any でも可。
 > example.org # ← 調べたい ISP のホスト名
Default Server: XXX.XXX.ne.jp
Address: XXX.XXX.XXX.XXX
 
Non-authoritative answer:
example.org nameserver = a.iana-servers.net
example.org nameserver = b.iana-servers.net # ←DNSサーバのホスト名
 
Authoritative answers can be found from:
b.iana-servers.net internet address = 193.0.0.236 # ←DNS サーバの IP アドレス

この結果として返ってきた DNS サーバの IP アドレスを名前解決用 DNS サーバとして指定できます(できないこともあります)。
ただし、自分が所属している ISP 、ネットワーク以外を指定するとはじかれることがありますし、ネットワーク的に遠いと遅いこともままあるので、自分の IP アドレスの逆引きから調べるようにしたほうがいいでしょう。

テーブルロックの話

テーブルロックをうまく使うと、
・MyISAM でのパフォーマンス向上
・MyISAM で(InnoDB を使わずに)簡易的にトランザクションの一部機能を実現できる
といううまみがある。(InnoDB, BDB だと逆効果になりうる。
 
テーブルロックの基本的なクエリは次のとおり。
 
– 読み込みロック

LOCK TABLES foo READ

テーブルの読み込みロッククエリを実行すると、ロック中は現在の接続(と同時に実行中の他の全ての接続)で、指定したテーブル(例では `foo`)の更新が一切できなくなる。
複数の参照系クエリを連続で送る時に、途中でデータが書きかわると困る場合に利用する。サブクエリなどを使って1クエリにまとめてしまっている場合は不要。
 
別の接続で書き込みロックが発生している場合は、読み込みロックを獲得するまで待ちに入る。
なお、読み込みロックは性質的にパフォーマンスを向上させるものではなさそう。
 
– 書き込みロック

LOCK TABLES foo WRITE

テーブルの書き込みロッククエリを実行すると、ロック中は現在の接続以外からしか読み書きができなくなる。既にロック(読み/書きいずれか)が発生している場合はロックが獲得できるまで待ちに入る。また、デフォルトで READ よりも優先度が高い。
 
書き込みロックによってパフォーマンスが向上する可能性があるのは、処理時間の短いクエリを多く実行する場合(ロック解除時にまとめて実行するようになるため)。
 
更新を1回のクエリでしか実行しないのであれば、書き込みロックは不要。

(MySQL 4.1 公式リファレンスマニュアルより)
LOCK TABLES の使用時にいくつかの面で処理が迅速になる理由は、
MySQL でキーのキャッシュが UNLOCK TABLES が呼び出されるまで
フラッシュされないためである(通常、キーのキャッシュは各 SQL
ステートメントの後にフラッシュされる)。
それによって、MyISAM テーブルに対する挿入、更新、削除処理が
迅速化される。

 
– ロック解除

UNLOCK TABLES

テーブルロック解除クエリが実行されるか接続が終了した時点で、現在のスレッドが保持している全てのテーブルロックを解除する。
WRITE ロックの場合はこの時点で実際にデータベース上の値を書き換える。
 
参考:
MySQL4.1 リファレンスマニュアル: LOCK TABLES および UNLOCK TABLES 構文
釣ったよ!釣りとコンピュータ: MySQL InnoDB の利用: テーブル・ロックについて