Opera が重い…わけではないが

結果的に重くなる。メモリをアホみたいに食って、しかも解放しないっぽいからだ。
Opera10になってさらにウチのマシンには重荷である。
最小化するとページアウトするんだっけ? でも重いときは最小化自体が重い。

個人的になじみの無い Win32API だらけで戦々恐々。
何も Opera に限ったわけでないコマンドラインツールにできそうだけどめんどいのでやらない。

動かしてみた結果、Opera プロセスのメモリ使用量が2000KBぐらいまで下がる(inタスクマネージャ)。
まぁそんなんで足りるわけないからすぐ膨れるけど。
しかし必要以上の肥大のカットはできそうっぽい。

opera_working_set_deallocator.c
#include <stdio.h>
#include <windows.h>

#define WINDOW_CAPTION_BUFFER_SIZE (512)

BOOL lookup_process_by_caption(const char *subject_caption, DWORD *found_dest);


int main(void){
  DWORD pid;
  HANDLE opera;
  
  if (!lookup_process_by_caption("Opera", &pid)){
    fprintf(stderr, "Opera's process can't find.");
    return -1;
  }
  
  opera = OpenProcess(PROCESS_SET_QUOTA, TRUE, pid);
  if (opera == NULL){
    fprintf(stderr, "Opera's process can't open.");
    return -1;
  }
  
  
  SetProcessWorkingSetSize(opera, -1, -1);
  
  CloseHandle(opera);
  return 0;
}


// Lookup Process

typedef struct tagLookupProcessCond{
  const char *subject_caption;
  DWORD       process_id;
  BOOL        found_p;
} LookupProcessCond;

BOOL CALLBACK lookup_process_by_caption_callback(HWND hWnd, LPARAM lParam){
  LookupProcessCond *cond = (LookupProcessCond *)lParam;
  char buf[WINDOW_CAPTION_BUFFER_SIZE];
  DWORD pid;
  
  GetWindowText(hWnd, buf, WINDOW_CAPTION_BUFFER_SIZE);
  if (strcmp(buf, cond->subject_caption) == 0){
    GetWindowThreadProcessId(hWnd, &pid);
    cond->process_id = pid;
    cond->found_p = TRUE;
    return FALSE; // break from enumeration
  }
  
  return TRUE;
}

BOOL lookup_process_by_caption(const char *subject_caption, DWORD *found_dest){
  LookupProcessCond cond;
  
  cond.subject_caption = subject_caption;
  cond.found_p = FALSE;
  EnumWindows(lookup_process_by_caption_callback, (LPARAM)(&cond));
  if (cond.found_p) *found_dest = cond.process_id;
  
  return cond.found_p;
}