メモリやCPU使用率が高すぎる?

このQ&Aのポイント
  • Java 1.6で動作するアナログ時計のようなものを作っていますが、メモリやCPUの使用率が常駐に向かない程度まで高くなってしまいます。
  • 具体的には、メモリが100MB前後、CPUが10%前後で安定しています。Intel Core i7 の10%はかなりの割合です。
  • ソースが全てではないので、大きな間違いや代替案等があれば教えていただきたいです。
回答を見る
  • ベストアンサー

メモリやCPU使用率が高すぎる?

Java 1.6で動作するアナログ時計のようなものを作っていて、 一応動作はするのですが、メモリやCPUの使用率が常駐に向かない程度まで高くなってしまいます。 具体的には、メモリが100MB前後、CPUが10%前後で安定しています。 増え続ける様子はないのですが Intel Core i7 の10%はかなりの割合です。 ここに書いているソースが全てではないのですが、大きな間違いや代替案等ありましたら教えていただけるとありがたいです。 Jpanel に 盤面、長針、短針、秒針 を描画するのが主な構造です。 秒針はスムーズに廻るタイプなので概ね30FPS程度の間隔で repaint() を呼んでいます。 アニメーションは専用のスレッドを使い、次のようにしています。 while(true){ try{Thread.sleep(sleepTime);}catch(InterruptedException ie){} SwingUtilities.invokeLater(new Runnable(){ public void run(){ paintPane.repaint(); } }); } JPanelのpaintComponentは次のとおりです @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g.create(); g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); g2d.scale(scale, scale); //shorthand.draw(g)などの描画処理 g2d.dispose(); 針の描画はこちらです。 public void draw(Graphics g){ angle=(角度の算出処理) Graphics2D g2d = (Graphics2D) g.create(); AffineTransform oldtr = ((Graphics2D)g).getTransform(); g2d.translate(this.posX - this.axisX, this.posY - this.axisY); g2d.rotate(Math.toRadians(angle), this.axisX, this.axisY; g2d.drawImage(this.image, 0, 0, null); g2d.setTransform(oldtr); g2d.dispose(); } 時計の針専用のクラスを用意し、針の画像、アングル、位置などの情報をもたせています。 全体のサイズは300x300ピクセル前後です。

  • Java
  • 回答数4
  • ありがとう数5

質問者が選んだベストアンサー

  • ベストアンサー
  • mpro-gram
  • ベストアンサー率74% (170/228)
回答No.4

私の考えつく単純な構成とは、かなり違うようです。 とりあえず、試したのは、クラス一つで構成しちゃいました。 時計描画用 JPanel に 時計背景、3つの針用にBufferedImageを保持して、このクラスをRunnableとして、描画専用にする。 このクラスには各画像の入れ替え用に setterメソッドも作っておく。あ、画像変更中にrepaint が行われないように、invokeLater しておくほうが無難なのか。 アプリケーション全体の方には、Menubar などのボタンに、画像切り替えなどのイベントを登録して、時計描画用クラスのsetterメソッドを呼ぶ。 時計のスタートは、時計描画用クラスの start()を呼んで開始、でもスレッドまわりは別クラスでスレッドを作って、このクラスをinvokeLaterの引数にセットするのでもメモリ消費や実行時間に影響はなさそうにみえました。 メモリ消費は保持する画像にもよるだろうけど、以下のようなクラスだと、そんなに、CPU時間は取らないみたいなので、どこで時間かかってるのかな?と思った次第です。 // import 文省略 public class AnalogClock extends JPanel implements Runnable{ private BufferedImage dial, hourNeedle, minNeedle, secNeedle; private java.awt.geom.AffineTransform af = new java.awt.geom.AffineTransform(); private int w,h,ox,oy, secX,minX,hourX, secY,minY,hourY; /* 回転中心変更用データを計算済みにして保持 */ public AnalogClock(){ /* default 画像作成または取り込み */ w = dial.getWidth(); h= dial.getHeight(); ox = w/2; oy = h/2; secX = secNeedle.getWidth() /2; secY = secNeedle.getHeight() /12; // hour,min も同様に } public void start(){ while( true ){ try{Thread.sleep(sleepTime);}catch(InterruptedException ie){} javax.swing.SwingUtilities.invokeLater(this); } } public void run(){ repaint(); } public void paintComponent(Graphics g){ super.paintComponent(g); g.drawImage(dial, 0,0, this); Graphics2D g2 = (Graphics2D)g; drawN(g2); } void drawN(Graphics2D g2){ java.util.Calendar rightNow = java.util.Calendar.getInstance(); /* 各時刻ごとに 新規取得 以下3つの針描画 */ double s = (double)rightNow.get(java.util.Calendar.SECOND) + rightNow.get(java.util.Calendar.MILLISECOND)/1000.0; double angle= s*6.0 -180 ; /* (角度の算出処理) 360*(sec/60) */ drawR(g2,secNeedle,angle,secX,secY); /* 同様に、分針、時針をdraw */ } void drawR(Graphics2D g2, BufferedImage img, double angle , int dx,int dy){ af.setToRotation(Math.toRadians(angle), dx, dy); /* dx,dy 中心に回転 */ double[] flat = new double[6]; af.getMatrix(flat); af.setTransform(flat[0], flat[1], flat[2], flat[3], flat[4]+ox-dx, flat[5]+oy-dy); g2.drawImage(img, af, this); } public void setSecNeedle(java.awt.image.BufferedImage img){ /* secNeedle に適宜描画し secX,secY を再計算 */ } /* 同様に長針短針文字盤用setterメソッド作成 */ }

django13
質問者

お礼

針ごとにオブジェクトを分けていない点やtranslate()を使っていない点を除けばおおまかな流れは極端にかけ離れてもいないようですね。 ためしに現状のソースから秒針以外のオブジェクトを取り除いて実質1クラスで動いているような状態にしてみましたがさほど大きな変化は見られないようでした。 他に負荷をかける要因として考えられるのは、バイリニアによる補間、倍率を指定しての描画、AWTUtilities.setWindowOpacity()とsetOpacity()によって非矩形ウィンドウにしている点ですが、外すわけにはいかない機能です。 他の機能といえばXMLから起動時の表示位置を読み出していることやコンテキストメニュー、タスクトレイアイコンくらいですがループ外にあるものなのでここでは省略しています。 C#で全く同じ機能を持つものを作ると1/6程度の負荷まで抑え込めたので結局はネイティブに近いフレームワークで作るしか無いのかもしれません。 Win/Mac対応が目的だったので残念ですがObjective-Cを勉強してみることにします。ありがとうございました。

その他の回答 (3)

  • mpro-gram
  • ベストアンサー率74% (170/228)
回答No.3

paintComponent() メソッド内部で、文字盤部分も毎回全部計算して描き直してると、1描画ごとに時間を喰う。それで、わざわざinvokeLaterなどしてるのだろうが、文字盤は変化しないのだから、BufferedImage に文字盤を作ってprivate propatyで保持しておいて、それを、paintComponentでは、drawImage1回で ボンとJPanelにコピーして上に針だけ書き直しするだけなら、各runにおける所用時間はかなり短縮すると思われる。メモリ的には、バッファー画像の分増えるかもだけど、他のところのobject多重生成が不要になって相殺されるんじゃないかな。 [Javaパフォーマンスチューニング:マルチスレッドによるリソース競合] の記事も読んで見られることをお薦めします。 http://www.atmarkit.co.jp/ait/articles/0505/14/news015.html  記事の日付は古いが、考慮すべきポイントはそう変わらないと思う。

django13
質問者

お礼

回答ありがとうございます。 文字盤自体は現状BufferedImageとしてプロパティに読み込んだPNGファイルをdrawImageで表示する構造を取っています。 ClockItem dial = new ClockItem(); // 部品用のクラス dial.loadImage("dial.png"); // 画像の読み込み dial.type = "dial"; // 役割の指定 針と盤面には共通のクラスにしてあり、描画時にtypeによって文字盤か長針、短針などを区別して、回転させるかそのままかを分けています。 g2d = (Graphics2D)g; dial.draw(g2d); // 役割に応じてBufferedImageをdrawImageします shorthand.draw(g2d); longhand.draw(g2d); secondhand.draw(g2d); 背景となる文字盤だけを一回のdrawImageで済ませるには背景用のJPanelに針用のJPanelを重ねたりするのでしょうか?

  • teketon
  • ベストアンサー率65% (141/215)
回答No.2

No.1の方も言ってるのに加えて >Graphics2D g2d = (Graphics2D) g.create(); この処理も初回だけでいいのでは?

django13
質問者

お礼

回答ありがとうございます。 create()自体をやめてGraphics2Dへのキャストするだけにして針側の処理でもそのGraphics2Dを再利用する形に変えてみました。フットプリントが100~300KB前後ですが減少したようです。 グラフ化してみると最初の2分ほどでピークに達し、徐々に減少して10分ほどでほぼ水平になりそれ以降はずっと水平です。2つの修正を施す前のソースでも同じようなグラフになりました。 青い線がヒープ使用量で、赤い線がヒープ合計です。 http://kie.nu/1_2A freeMemory()で得られるJava内のメモリは小さくなっているにもかかわらずWindowsやMacのリソースモニターで見るメモリ使用量は100MB前後まで増え続けてしまいます。 VMが使用している部分もあるとは思いますが、このようなものなのでしょうか?

  • hitomura
  • ベストアンサー率48% (325/664)
回答No.1

ざっと見ですが、 while(true){ try{Thread.sleep(sleepTime);}catch(InterruptedException ie){} SwingUtilities.invokeLater(new Runnable(){ public void run(){ paintPane.repaint(); } }); } で、while 中で毎回匿名インスタンスを生成しているのは生成・破棄の手間がかかるように見えます。 Runnable r = new Runnable(){ public void run(){ paintPane.repaint(); } }; while(true){ try{Thread.sleep(sleepTime);}catch(InterruptedException ie){} SwingUtilities.invokeLater(r); } という風にループ外に出したらわずかながら改善するかもしれません。

django13
質問者

お礼

回答有難うございます。 劇的な改善とまでは行きませんでしたが、確かに無駄のある書き方をしていたので教えていただいたように修正しました。

関連するQ&A

  • javaでgraphicsの描画の件

    今日は javaでgraphicsの描画を行っていますが、CENTERのペインには、描画できますが、 それ以外のペイン(NORTH,WEST、EAST,、SOUTH)には、描画できないように思います。 Q1)この件について、コメント頂けますと大変助かります。 下記に、ソースコードを添付いたします。 =================== package pkg; import java.awt.BasicStroke; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.geom.Line2D; import javax.swing.JFrame; import javax.swing.JPanel; public class SampleApp extends JFrame { public SampleApp(){ this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setSize(600, 300); this.add(new GPanel(), BorderLayout.WEST); this.add(new GPanel(), BorderLayout.CENTER); } public static void main(String[] args) { new SampleApp().setVisible(true); } } class GPanel extends JPanel { @Override public void paintComponent(Graphics g) { super.paintComponent(g); // int w = this.getWidth(); // int h = this.getHeight(); int w=200; int h=200; g.setColor(Color.RED); g.fillOval(0, 0, w/2, h/2); Graphics2D g2 = (Graphics2D)g; g2.draw(new Line2D.Double(40, 40, w,h)); g.setColor(Color.BLUE); g.setFont(new Font("Serif", Font.BOLD, 36)); g.drawString("Graphics draw!", 10, h - 50); // g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.draw(new Line2D.Double(30.0d, 50.0d, 180.0d, 140.0d)); g2.setPaint(Color.PINK); BasicStroke wideStroke = new BasicStroke(8.0f); g2.setStroke(wideStroke); g2.draw(new Line2D.Double(30.0d, 120.0d, 250.0d, 70.0d)); } }

    • ベストアンサー
    • Java
  • java repaint()に関して

    プログラムで以下のpaintComponents内のデバックができません。 理由は一体何なのでしょうか? お願いします。 import java.awt.Graphics; import javax.swing.JPanel; public class MainPanel extends JPanel implements Runnable { Thread th; public MainPanel() { super(); } public void movestart() { th = new Thread(this); th.start(); } public void paintComponent(Graphics g) { System.out.println("このデバックができない"); super.paintComponent(g); } public void run() { while (true) { System.out.println("ここのデバックはできている"); repaint(); try { th.sleep(100); } catch (Exception e) { } } } }

    • ベストアンサー
    • Java
  • JButtonの画像をactionPerformedメソッド内で再描画

    JButtonの画像をactionPerformedメソッド内で再描画したい。 以下のソースのようにして、再描画したいのです。 setIconメソッドではなく、 JButtonに対して描画したものに対して再描画したいです。 Graphics2DクラスについてJAVA APIで調べましたが、 仕組の理解に至りませんでした。 仕組みと方法を教えて頂きたいです。 よろしくお願いいたします。 import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JFrame; public class test extends JFrame implements ActionListener{ JButton b= new JButton(); public static void main(String a[]) { new test(); } public test() { super(); this.setSize(100,100); b.addActionListener(this); b.add(new Zoom(new ImageIcon("img1.jpg"),0,0,50,50)); this.add(b); this.setVisible(true); } class Zoom extends JComponent { private static final long serialVersionUID = 1L; private ImageIcon icon = null; private int x = 0; private int y = 0; private int h = 0; private int w = 0; private double scale = 1.0d; public Zoom(ImageIcon icon, int x, int y, int w, int h) { super(); this.icon = icon; this.x = x; this.y = y; this.w = w; this.h = h; } public void paintComponent(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.scale(scale, scale); ////////////////////////////////// //画僧を再描画したい。 //g2.clearRect(0, 0, 80, 80);//× g2.drawImage(icon.getImage(), x, y, w, h, this); } } public void actionPerformed(ActionEvent e) { if(e.getSource()==b){ System.out.print("ok"); //this.repaint();//× //b.repaint();//× b.add(new Zoom(new ImageIcon("img2.jpg"),0,0,50,50));//(再描画できない) //b.setIcon(new ImageIcon("img2.jpg"));//ok(再描画出来る) } } }

    • ベストアンサー
    • Java
  • javaのCanvasを使用する描画

    今日は! repaintからCanvasの中のpaintルーチンを起動して描画を行なっています。 (下記のプログラム参照) ボタンを押すごとに、キャンバスに違った内容の書込みを行ないます。 painルーチンが起動する度に、既に書込んだキャンバスの内容がクリヤーされて 新規にキャンバスに書込みが行われて居ると思います。 Q1)キャンバスの内容をクリヤーすることなく、既に書込んだキャンバスの内容を 残して、その上に書込む方法はありませんか? (クリヤーのための指令は、出していないと思っています) ご教授の程、宜しくお願いします。 //================================ import java.awt.BasicStroke; import java.awt.BorderLayout; import java.awt.Button; import java.awt.Canvas; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.geom.Line2D; import javax.swing.JFrame; import javax.swing.JPanel; public class ShapeTest1 extends JFrame{ int sw=0; myCanvasPanel myCanvas; public static void main(String[] args){ // JFrame frame = new JFrame(); ShapeTest1 frame=new ShapeTest1(); } ShapeTest1(){ JFrame frame=new JFrame(); // ShapeTest1 app = new ShapeTest1(); // frame.getContentPane().add(app); frame.setTitle("タイトル"); frame.setBounds(10, 10, 300,220); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // frame.setVisible(true); //North========================= JPanel p1=new JPanel(); myCtlPanel myCtl=new myCtlPanel(p1) ; // frame.getContentPane().add(p1,BorderLayout.SOUTH); frame.getContentPane().add(p1,BorderLayout.NORTH); //===================================== JPanel p2=new JPanel(); myCanvas=new myCanvasPanel(p2); p2.add(myCanvas); frame.getContentPane().add(p2,BorderLayout.CENTER); frame.setVisible(true); } //=========================== class myCtlPanel extends JFrame{ myCtlPanel(JPanel p){ /* //領域のサイズ設定 setSize(300,50); //領域のサイズ取得 Dimension dimension = getSize(); */ Button button1=new Button("button1"); button1.addActionListener(new TimButton1()); p.add(button1); } } class TimButton1 implements ActionListener{ @Override public void actionPerformed(ActionEvent ae){ if(sw==0){ sw=1; } else{ sw=0; } myCanvas.repaint(); //ng System.out.println("TimButton1 sw="+sw); } } class myCanvasPanel extends Canvas{ myCanvasPanel(JPanel p){ //領域のサイズ設定 setSize(300,150); //領域のサイズ取得 Dimension dimension = getSize(); // p.add(this); } // public void paintComponent(Graphics g){ //repaint()では、起動されない public void paint(Graphics g){ //repaint()では、起動 Graphics2D g2 = (Graphics2D)g; System.out.println("Paint sw="+sw); if(sw==0){ //================================================ g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.draw(new Line2D.Double(30.0d, 50.0d, 180.0d, 140.0d)); //============================================== g2.setPaint(Color.PINK); BasicStroke wideStroke = new BasicStroke(4.0f); g2.setStroke(wideStroke); g2.draw(new Line2D.Double(30.0d, 120.0d, 250.0d, 70.0d)); } else{ g2.setPaint(Color.RED); BasicStroke wideStroke = new BasicStroke(4.0f); g2.setStroke(wideStroke); g2.draw(new Line2D.Double(30.0d, 120.0d, 250.0d, 140.0d)); } } } }

    • ベストアンサー
    • Java
  • MouseEventのつけ方

    MouseEventのMouseEneterdに関することなのですが、 扇形をいくつか合わせて円を描画する、いわゆるパイメニューみたいなものを作成するときに、 各パイ上にマウスポインタがきた時に選択されたことがわかるように色を変えたりしたいのですが、 四角形ではなく扇形なので座標指定方法がよくわかりません。 public void paint(Graphics g) { Graphics2D g2 = (Graphics2D)g; g2.setColor(Color.BLACK); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.draw(new Arc2D.Double(100,100,200,200,0,120,Arc2D.PIE)); g2.draw(new Arc2D.Double(100,100,200,200,120,120,Arc2D.PIE)); g2.draw(new Arc2D.Double(100,100,200,200,240,120,Arc2D.PIE)); }}; どのようにしたらうまく描画できるのでしょうか。 ちなみにプログラム全体は大きなウィンドウ(JFrame)を表示しその一部分にこの円を描画しています。JDesktopPane上で実装しているので、実際はJPanelにこの円を描画してパネルを貼り付けています。 いろいろ調べてみたのですが、よくわかりません。 もっと他にいい描画方法等があればそちらも教えていただけると幸いです。 よろしくお願いします。

    • ベストアンサー
    • Java
  • SwingのpaintComponent()メソッドについて

     JAVA初心者です、宜しくお願いします。  参考書で、Swingについて以下のようなコメントを見つけました、ただ何故そうなのかの理由を書いていません。  以下の内容はどのような理由からそうなるのでしょうか。  「Swing コンポーネントでは、メソッドpaintは推奨されていません。  paintComponentをプログラムから呼び出してはいけません。描画をしたい場合は、 paintComponent をオーバー ライドしたクラスの repaint() メソッドを呼び出します。  Swing コンポーネント上に描画するには、 描画したいコンポーネントのクラスを継承したクラスで、 メソッド paintComponent(Graphics g) をオーバーライドし、 パラメータで渡された g に対して Graphics クラスのメソッドで描画をします。  オーバーライドした paintComponent の先頭で、このコンポーネントの土台を描画するために、 super.paintComponent(g) を呼び出しておきます。」  宜しくお願いします。

    • ベストアンサー
    • Java
  • BufferedImageへの変換エラーです

     こんにちは。java初心者です、宜しくお願いします。  BufferedImageに変換したいんですが、引数の取り方が分かりません。  "srcimage1"を"BufferedImage" 、"Image"で取ってやっても"BufferedImageにキャスト出来ま せん"という意味のエラー表示が出るばかりでお手上げです。    どなたか詳しい方、エラーの原因についてどうか宜しくお願いします。 ========================================= public class BufferedImage1 extends Applet { static BufferedImage srcimage1 , newimg ; static Image srcimage0 ; //static BufferedImage srcimage0 ; static BufferedImage source ; static BufferedImage target ; static Graphics g ; static Graphics2D g2 ; static Image img ; public void init() { this.setLocation( 0 , 0 ) ; setBackground( Color.red ) ; g2 = (Graphics2D)g ; srcimage0 = getImage( getDocumentBase() , "a.gif" ) ; srcimage1 = ( BufferedImage )srcimage0 ; newimg = change(srcimage1 , new BufferedImage(100 , 100 , BufferedImage.TYPE_4BYTE_ABGR_PRE)) ; } public void paint(Graphics g) { g2.drawImage(newimg , 0 , 0 , null ) ; } public BufferedImage change( BufferedImage source , BufferedImage target) { this.source = source ; this.target = target ; Graphics2D g2 = target.createGraphics() ; g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION , RenderingHints.VALUE_INTERPOLATION_BICUBIC) ; double scalex = (double) target.getWidth() / source.getWidth() ; double scaley = (double) target.getHeight() / source.getHeight() ; AffineTransform xform = AffineTransform.getScaleInstance(scalex , scaley) ; g2.drawRenderedImage(source , xform) ; g2.dispose() ; return target ; } }

    • ベストアンサー
    • Java
  • 上に色をつけるJPanelを作りたい

    つい先日も質問させていただきましたが、また分からないことがでてきたのでお聞きします。 JPanelのなかにOverlayLayoutで2枚のJPanel(上にglassPane、下にcontentPane)を配置し、overがtrueになったらglassPaneに色を書くようにしたいと思っています。 ですが、下のcontentPane部分にボタンなどがあると、その部分にうまく色がつきません。 どうすればいいのでしょうか。よろしくお願いします。 自分で組んでみたコードを示します。 ****** import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Test extends JLabel{ private JPanel glassPane; private JPanel contentPane = new JPanel(); private JButton button1 = new JButton("OverlayTest"); private boolean over = false; public Test(){ glassPane = new JPanel(){ @Override protected void paintComponent(final Graphics g) { super.paintComponent(g); if(!over)return; Graphics2D g2 = (Graphics2D) g; g2.setColor(new Color(Color.MAGENTA.getRed(), Color.MAGENTA.getGreen(), Color.MAGENTA.getBlue(), 150)); g2.fillRect(0, 0, this.getWidth(), this.getHeight()); } }; button1.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { setOver(!over); glassPane.repaint(); //glassPane.revalidate(); } }); contentPane.setLayout(new GridBagLayout()); contentPane.add(button1); glassPane.setOpaque(false); setLayout(new OverlayLayout(this)); add(glassPane); add(contentPane); } public void setOver(boolean over){ this.over = over; } public static void main(String[] args) { JFrame frame = new JFrame(); frame.add(new Test()); frame.setSize(500,400); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } }

    • ベストアンサー
    • Java
  • tabにdrawImageで画像を描画したい

    tabにdrawImageで画像を描画したい 以下のソースでtabbedpaneに対して、ImageIconを指定して画像をのせるではなく、 drawImageメソッドで描画したいです。 ご存知の方がおられましたら教えてください。 import javax.swing.*; import java.awt.BorderLayout; import java.awt.Graphics; import java.awt.Graphics2D; public class JTabbedPaneTest4 extends JFrame { Zoom zoom = null; public static void main(String[] args) { JTabbedPaneTest4 frame = new JTabbedPaneTest4(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setBounds(10, 10, 300, 200); frame.setVisible(true); } JTabbedPaneTest4() { JTabbedPane tabbedpane = new JTabbedPane(); JPanel tabPanel1 = new JPanel(); tabPanel1.add(new JButton("button1")); ImageIcon icon1 = new ImageIcon("img1.jpg"); zoom = new Zoom(icon1, 0, 0, 50, 50); //tabbedpane.addTab("tab1", icon1, tabPanel1);//ok //tabbedpane.add(zoom, tabPanel1);//ng(パネルに書き込まれてしまう) getContentPane().add(tabbedpane, BorderLayout.CENTER); } class Zoom extends JComponent { private static final long serialVersionUID = 1L; private ImageIcon icon = null; private int x = 0; private int y = 0; private int h = 0; private int w = 0; private double scale = 1.0d; public Zoom(ImageIcon icon, int x, int y, int w, int h) { super(); this.icon = icon; this.x = x; this.y = y; this.w = w; this.h = h; } public void paintComponent(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.scale(scale, scale); g2.drawImage(icon.getImage(), x, y, w, h, this); } } }

    • ベストアンサー
    • Java
  • javaでメモリ使用量が増え続ける

    public class Main extends JFrame{ public static void main(String args[]){ Main frame = new Main("test"); frame.setVisible(true); } Main(String title){ setTitle(title); setBounds(100, 100, 300, 250); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public void paint(Graphics g){ Graphics2D g2 = (Graphics2D)g; BufferedImage readImage = null; try { readImage = ImageIO.read(new File("ファイルへのパス")); } catch (IOException e) { e.printStackTrace(); } g2.drawImage(readImage, 0, 0, this); readImage.flush(); g.finalize(); g2.finalize(); g.dispose(); g2.dispose(); } } いま、画像を表示するプログラムを上のように書いたのですが、ウィンドウのサイズを変更したりしてpaintが呼ばれるごと(多分)にメモリの使用量が増えていきます。 そして、メモリの使用量が減ることはなく常に増えてしまってます。 windowsのタスクマネージャーでメモリの使用量は見てます。 なぜこのようなことが起こってしまうのでしょうか?? また、どのようにすればメモリの使用量が増えることがないようにすることができるでしょうか?? よろしくお願いします。