¿Qué es un Fidget Spinner?

Construir un fidget spinner con el lenguaje Java en el IDE JDeveloper 11g 

 Un fidget spinner es un juguete que se dice que es “antiestrés”, hecho de plástico, metal y otros materiales. Constituido con un eje central con dos, tres o más brazos que giran sobre su eje.

Construir un fidget spinner virtual. 

En la imagen está la estructura de clases a crear en una aplicación Java


Interfaz gráfica para el fidget spinner. 

En la imagen está la estructura de componentes para la vista


Código fuente. Clases para construir el fidget spinner

  
package client;

import com.sun.awt.AWTUtilities;

import java.awt.BorderLayout;
import java.awt.Dimension;

import java.awt.Point;
import java.awt.Rectangle;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import java.awt.event.MouseAdapter;

import java.awt.event.MouseEvent;

import java.awt.event.MouseMotionAdapter;

import java.awt.event.WindowAdapter;

import java.awt.event.WindowEvent;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JToolBar;
import javax.swing.SwingConstants;

public class VentanaPrincipal extends JFrame {
    private Reloj reloj = new Reloj(){
        @Override
        public void notificarVista() {
            miNotificarVista();
        }
    };
    private Tablero tablero = new Tablero();
    private JToolBar jToolBar1 = new JToolBar();
    private JButton jButton1 = new JButton();
    private JButton jButton2 = new JButton();
    private JButton jButton3 = new JButton();
    private JLabel jLabel1 = new JLabel();
    private JLabel jLabel2 = new JLabel();
    private JButton jButton4 = new JButton();
    private JButton jButton5 = new JButton();
    private JButton jButton6 = new JButton();
    private JButton jButton7 = new JButton();
    private boolean flotar =  true;
    private JPanel jPanel1 = new JPanel();
    private JButton jButton8 = new JButton();

    public VentanaPrincipal() {
        try {
            jbInit();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void jbInit() throws Exception {
       
        this.getContentPane().setLayout(null);
        this.setSize(new Dimension(423, 497));
        this.setTitle("Fidget Spinner - Juguete antiestrés");
        this.setResizable(false);
        this.addWindowListener(new WindowAdapter() {
                public void windowIconified(WindowEvent e) {
                    this_windowIconified(e);
                }

                public void windowDeiconified(WindowEvent e) {
                    this_windowDeiconified(e);
                }
            });
        tablero.setBounds(new Rectangle(5, 45, 400, 410));
        tablero.setSize(new Dimension(400, 400));
        tablero.setLayout(null);
        tablero.setOpaque(false);
        jToolBar1.setBounds(new Rectangle(0, 0, 420, 40));
        jToolBar1.setRollover(true);
        jToolBar1.setFloatable(false);
        jButton1.setText("Parar");
        jButton1.setToolTipText("Detener giro");
        jButton1.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    jButton1_actionPerformed(e);
                }
            });
        jButton2.setText("+");
        jButton2.setToolTipText("Aumenta la velocidad");
        jButton2.setPreferredSize(new Dimension(20, 20));
        jButton2.setMinimumSize(new Dimension(20, 20));
        jButton2.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    jButton2_actionPerformed(e);
                }
            });
        jButton3.setText("-");
        jButton3.setToolTipText("Disminuye la velocidad");
        jButton3.setMinimumSize(new Dimension(20, 20));
        jButton3.setPreferredSize(new Dimension(20, 20));
        jButton3.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    jButton3_actionPerformed(e);
                }
            });
        jLabel1.setText("RPM=");
        jLabel1.setToolTipText("Revoluciones por minuto");
        jLabel2.setText("6.0");
        jButton4.setText("FS 1");
        jButton4.setToolTipText("Fidget Spinner 1");
        jButton4.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    jButton4_actionPerformed(e);
                }
            });
        jButton5.setText("FS 2");
        jButton5.setToolTipText("Fidget Spinner 2");
        jButton5.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    jButton5_actionPerformed(e);
                }
            });
        jButton6.setText("X");
        jButton6.setToolTipText("Cerrar");
        jButton6.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    jButton6_actionPerformed(e);
                }
            });
        jButton7.setText("=");
        jButton7.setToolTipText("Encima de las ventanas");
        jButton7.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    jButton7_actionPerformed(e);
                }
            });
        jButton8.setText("_");
        jButton8.setToolTipText("Minimiza la ventana");
        jButton8.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    jButton8_actionPerformed(e);
                }
            });
        jToolBar1.add(jButton1, null);
        jToolBar1.add(jButton2, null);
        jToolBar1.add(jButton3, null);
        jToolBar1.add(jLabel1, null);
        jToolBar1.add(jLabel2, null);
        jToolBar1.add(jButton4, null);
        jToolBar1.add(jButton5, null);
        jPanel1.add(jButton8, null);
        jPanel1.add(jButton7, null);
        jPanel1.add(jButton6, null);
        jToolBar1.add(jPanel1, null);
        this.getContentPane().add(jToolBar1, BorderLayout.NORTH);
        this.getContentPane().add(tablero, BorderLayout.CENTER);
        this.setAlwaysOnTop(flotar);
        tablero.addMouseListener(new MouseAdapter() {
                public void mouseClicked(MouseEvent e) {
                    jPanel1_mouseClicked(e);
                }
            });
        tablero.addMouseMotionListener(new MouseMotionAdapter() {
                public void mouseDragged(MouseEvent e) {
                    tablero_mouseDragged(e);
                }
            });
        tablero.setAltoAncho(400, 400);
        this.setUndecorated(true);
        AWTUtilities.setWindowOpaque(this, false); //setWindowOpacity (this,0.5f);
        reloj.start();
        tablero.LanzarJuego(jLabel2);
        tablero.repaint();
       
    }
    public static void main(String[] args) {
      VentanaPrincipal vp = new VentanaPrincipal();
      vp.setDefaultCloseOperation(vp.EXIT_ON_CLOSE);
      vp.setLocationRelativeTo(null);
      vp.setVisible(true);
    }
    private void miNotificarVista(){
        jLabel2.setText(""+(int)Math.floor(Globales.incremento*50));
        //if(!(this.getState()==this.NORMAL)) {
        //    Globales.Minimizado=true;
        //}else{
        //    Globales.Minimizado=false;
        //}
    }
    private void jButton1_actionPerformed(ActionEvent e) {
        Globales.incremento=(float)0.1;
        Globales.giro=(float)0.0;
    }

    private void jButton2_actionPerformed(ActionEvent e) {
        float incrementar = (float)(Math.random() * (double)1.0);
        Globales.incremento=Globales.incremento + incrementar;
    }

    private void jButton3_actionPerformed(ActionEvent e) {
        float incrementar = (float)(Math.random() * (double)1.0);
        float velocidad = Globales.incremento - incrementar;
        if(velocidad > (float)0.1) {     
          Globales.incremento = velocidad;
        }else{
          Globales.incremento = (float)0.1;
        }
    }

    private void jPanel1_mouseClicked(MouseEvent e) {
        int nClick = e.getClickCount();
        if(nClick==1){
            float incrementar = (float)(Math.random() * (double)1.5);
            float velocidad = Globales.incremento + incrementar;
            Globales.incremento=velocidad;
        }else{
            float incrementar = (float)(Math.random() * (double)1.0);
            float velocidad = Globales.incremento - incrementar;
            if(velocidad > (float)0.1) {
              Globales.incremento=velocidad;       
            }else{
              Globales.incremento=(float)0.1;
            }
        }
    }

    private void jButton4_actionPerformed(ActionEvent e) {
        tablero.setFS01();
    }

    private void jButton5_actionPerformed(ActionEvent e) {
        tablero.setFS02();
    }

    private void jButton6_actionPerformed(ActionEvent e) {
        System.exit(0);
    }
    private void jButton7_actionPerformed(ActionEvent e) {
        if(flotar==true){
            this.setAlwaysOnTop(false);
            flotar=false;
            jButton7.setText("--");
        }else{
            this.setAlwaysOnTop(true);
            flotar=true;           
            jButton7.setText("=");
        }
    }

    private void jButton8_actionPerformed(ActionEvent e) {
        this.setState(this.ICONIFIED);
    }
    Point point = null;
    private void tablero_mouseDragged(MouseEvent e) {     
        point = e.getLocationOnScreen();
        this.setLocation(point.x-(400/2), point.y-(400/2));
    }

    private void this_windowIconified(WindowEvent e) {
        Globales.Minimizado=true;  
    }

    private void this_windowDeiconified(WindowEvent e) {
        Globales.Minimizado=false;
    }
}


package client;

import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.LayoutManager;

import java.awt.RenderingHints;

import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Tablero extends JPanel {
    private ImageIcon fs01 = new ImageIcon(getClass().getResource("/recursos/fs01.png"));
    private ImageIcon fs02 = new ImageIcon(getClass().getResource("/recursos/fs02.png"));
    private Image fs03 = null;
    private Graphics2D g2d = null;
    private int alto = 0;
    private int ancho = 0;
    private int xCentro = 0;
    private int yCentro = 0;
    private Ciclo ciclo = new Ciclo() {
        @Override
        public void mover() {
            miRepaint();
        }
    };

    public void setAltoAncho(int alto, int ancho) {
        this.alto = alto;
        this.ancho = ancho;
        this.xCentro = ancho / 2;
        this.yCentro = alto / 2;
    }

    public Tablero() {
        super();
        try {
            jbInit();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void LanzarJuego(JLabel jl) {
        fs03 = fs02.getImage();
        ciclo.start();
    }

    public void setFS01() {
        fs03 = fs01.getImage();
    }

    public void setFS02() {
        fs03 = fs02.getImage();
    }

    public void paint(Graphics g) {
        super.paint(g);
        g2d = (Graphics2D)g;
        g2d.translate(xCentro, yCentro);
        //g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.rotate(Globales.giro); //(0 < giro < (2*PI)) * K_incremento
        g2d.drawImage(fs03, -xCentro, -yCentro, ancho, alto, null);
    }

    private void miRepaint() {
        this.repaint();
    }

    public void update(Graphics g) {
        // super.update(g);
        return; //anular el método update(...)
    }

    private void jbInit() throws Exception {
        this.setSize(new Dimension(400, 400));
    }
}

package client;

public abstract class Reloj extends Thread {

    public Reloj() {
        super();
    }

    public void run() {
        super.run();
        do {
            try {
                this.sleep(500);
                notificarVista();
            } catch (InterruptedException e) {
            }
        } while (true);
    }

    public abstract void notificarVista();
}

package client;

public class Globales {
    public static float incremento = (float)0.1; //para 1 es 1 rpm - para 0.1 es 10 rpm
    public static float giro= (float)0.0; //(0 < giro < (2*PI)) * K_incremento
    public static boolean Minimizado = false;
    public Globales() {
        super();
    }
}

package client;

public abstract class Ciclo extends Thread  {
    public Ciclo() {
        super();
    }
    private final int fps = 1000/50; //20 cuadros por segundos
    private final float arco = (float)((Math.PI*(double)2) / (double)50.0); //pizza de 50 porciones
    private final float frenado = (float)0.001;
    public void run() {
        super.run();
        while (true) {
            mover();
            Globales.giro = Globales.giro + (arco * Globales.incremento);
            if(Globales.incremento > 0.0) {
              Globales.incremento = Globales.incremento - frenado;
            }else{
              Globales.incremento = (float)0.1; 
            }
            if(Globales.giro > 9999999) Globales.giro = (float)0.0;
            try {
                if(Globales.Minimizado==false) {
                    this.sleep(fps);
                }else{
                    this.sleep(1000);
                }
               
            } catch (InterruptedException e) {
            }
        }
    }

    public abstract void mover();
}

Diagrama de clases 


Desarrollo del producto software

Descargar el desarrollo y el ejecutable JAR del fidget Spinner Descargar

¿Qué es Jitter Click?


Software para entrenar la técnica Jitter Click

El Jitter Click es una técnica utilizada para lograr mayor velocidad de click con el ratón, consiste básicamente en hacer vibrar o temblar la mano al hacer click con el ratón, el entrenamiento constante da una mayor velocidad de clicks, sirve sobre todo para el enfrentamiento del PVP (player vs player, jugador contra jugador) en juegos de computadoras.

Cuando se está jugando en un juego de computadoras es importante mantener un ritmo de click estable y a la mayor rapidez posible. Click x Segundos – Jitter Click permite practicar y encontrar el máximo ritmo posible para un ratón gamer. Si el ritmo es muy lento o muy rápido se producen fallos en los click para una computadora y ratón particular, es necesario encontrar el ritmo justo de clicks para ganar en juegos de computadoras.
Cada ratón y cada computadora tendrán un ritmo particular de click, una computadora con pocos recursos que pueda jugar haciendo click a un ritmo justo y estable sin producir fallos por excesos de click le puede ganar a una computadora gamer con más recursos.
Descargar el archivo JAR ejecutable con la Máquina Virtual Java
Descargar el archivo JAR
Descargar el archivo RAR con el desarrollo del software en el IDE JDeveloper 11g de Oracle
Descargar el desarrollo del producto software

Ejemplo de código Java para comprender el funcionamiento del componente JList

Ejemplo del componente JList de Java usando el IDE JDeveloper 11g

  • Modelo de datos para un JList
  • Modelo de Selección para un JList
    • Soporte de cambios en la selección de un JList

Para usar el componente  JList de Java hay que comprender el modelo de datos para la lista de objetos que el JList puede mostrar en su vista. El componente JList tiene un modelo de selección que gestiona los elementos seleccionados en la vista del JList.


El componente JList de Java es el ejemplo perfecto de la aplicación del patrón MVC (Modelo Vista Controlador).

Con el modelo de datos se puede borrar, editar y agregar objetos a la lista de objetos del componente JList. 

La siguiente clase puede gestionar todas las posibles operaciones sobre el modelo de datos perteneciente a un JList.

package client;

import javax.swing.DefaultListModel;

public class MiHerenciaDefaultListModel extends DefaultListModel {
    public MiHerenciaDefaultListModel() {
        super();
    }
    public void agregarDatos(){
        addElement("José");
        addElement("Pedro");
        addElement("aaaa");
        addElement("dddd");
    }
    public void add(int index, Object element) {
        super.add(index, element);
    }

    public void setElementAt(Object obj, int index) {
        super.setElementAt(obj, index);
    }

    public void removeElementAt(int index) {
        super.removeElementAt(index);
    }
}

Forma de usar en la vista:

private MiHerenciaDefaultListModel mHDLM = new MiHerenciaDefaultListModel();

        jList1.setModel(mHDLM);
        mHDLM.agregarDatos();



Con el modelo de selección se puede saber que elementos de la lista se han seleccionado, los elementos seleccionados pueden convertirse en un modelo de datos para operar con ellos. En la siguiente imagen se han seleccionado los elementos María y Alberto.

La siguiente clase se encarga de gestionar la detección de un cambio en la selección de los datos en un JList y de notificar a la vista que la selección ha cambiado.

package client;

import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

public abstract class MiInterfazDeEscucha implements ListSelectionListener {

    public MiInterfazDeEscucha() {
        super();
    }

    @Override

    public void valueChanged(ListSelectionEvent e) {
        ListSelectionModel lsm = (ListSelectionModel)e.getSource();
        notificarVista(e);
    }

    public abstract void notificarVista(ListSelectionEvent e);
}


Forma de usar en la vista:

private DefaultListSelectionModel dlsm = new DefaultListSelectionModel();
private MiInterfazDeEscucha mIDE = null;

        mIDE=new MiInterfazDeEscucha(){
          @Override
          public void notificarVista(ListSelectionEvent e) {
              ListSelectionModel lsm = (ListSelectionModel)e.getSource()
              …
          } 
        };
        dlsm = (DefaultListSelectionModel)jList1.getSelectionModel();
        dlsm.addListSelectionListener(mIDE);
     


Para saber más sobre el componente JList visitar las siguientes páginas:

Código para pegar en un Blog Amigo:

Desarrollo de software en un régimen ágil con un enfoque de ingeniería del software

Trabajando en un régimen de metodología ágil

Rol del programador

Si eres programador y te encuentras trabajando en un proyecto de construcción de un producto software bajo una metodología ágil tienes que aprender a entregar desarrollo de software rápidamente, un programador tiene que aprender a tomar un requerimiento de usuario del sistema y hacer una entrega rápida del análisis, diseño y código. El código se puede entregar en tres formas:  

 Tipos de prototipos

  • Prototipo de usar y descartar (maqueta, simulación), aprendizaje y auto regulación del proyecto
  • Prototipo reutilizable (incremental), agregan nuevos requerimientos
  • Prototipo de código final (evolutivo), integración con el sistema final y se generan nuevas versiones

Una de las metodologías ágiles es el SCRUM, está guiado por una pila de requerimientos de donde se saca un conjunto de ellos y se los hace pasar por una etapa llamada Sprint, el Sprint tiene revisiones diarias y su duración es de 2 semanas en promedio.

Las metodologías ágiles tienen el objetivo de hacer entregas rápidas de software funcional al usuario del sistema. El programador debe adquirir la habilidad de crear software basado en los requerimientos de usuario.


Sistema Operativo – Memoria RAM física y memorias RAM virtual

Gestión de memoria RAM en los Sistemas Operativos


Paginación


La paginación permite que la memoria usada de un proceso no sea contigua, a un proceso se le asigna memoria física donde esté disponible.

La paginación evita el gran problema de acomodar trozos de memoria RAM física para alojar procesos de tamaño variable. De esta forma se simplifica el intercambio de páginas entre la RAM física y la memoria de almacenamiento auxiliar de disco fijo.

Permite intercambiar fragmento de códigos o datos que residen en la memoria principal y la memoria virtual, hay que encontrar espacio en el almacenamiento auxiliar del disco fijo para volcar páginas de la memoria RAM física.

Por sus ventajas la paginación es de uso común en muchos Sistemas Operativos.

Estructura de una memoria RAM de 32 Bits (32 bits son equivalente a una memoria RAM de 4 Giga Bytes)


00:00
Dirección de memoria 1
00:01
Dirección de memoria 2
..
..
..
..
FF:FF
Dirección de memoria  4.294.967.296

Los 4.294.967.296 de direcciones de una memoria RAM son divididos en segmentos, los segmentos son divididos en marcos, los marcos son divididos en páginas.

Segmentar una memoria RAM en segmentos, marcos y páginas


  • Una memoria RAM de 4GB se puede dividir en 65536 segmentos de 65536 direcciones
  • Un segmento se puede dividir en 256 marcos de 256 direcciones
  • Un marco se puede dividir en 16 páginas de 16 direcciones

Paginación


¿Qué es y cómo funciona la paginación?


La paginación es uno de los esquemas de manejo de memoria en donde un computador puede almacenar y recuperar datos de un dispositivo de almacenamiento secundario para su uso en la memoria principal. En el esquema de manejo de memoria de paginación, el sistema operativo recupera datos desde un dispositivo de almacenamiento secundario en bloques de un mismo tamaño llamados páginas. La principal ventaja de paginación sobre la segmentación de memoria es que permite al espacio de dirección física de un proceso ser no contiguo. Antes de la paginación, los sistemas debían poner programas en almacenamiento de forma contigua, lo que causaba varios problemas de almacenamiento y fragmentación.

Una de las dificultades de la paginación es que también produce fragmentación si el sistema no dispone suficiente memoria RAM física. Si el sistema dispone de suficiente memoria RAM física el mecanismo de paginación es muy eficiente y produce un incremento en la velocidad de ejecución de procesos por parte de la CPU.

Los procesos se dividen en páginas


Los sistemas operativos son los encargados de tomar un archivo ejecutable del disco fijo y dividir sus procesos en páginas de memoria RAM. Cada proceso tiene su propia tabla de páginas y es responsable el sistema operativo de gestionar la ejecución de cada página y de la tabla de páginas. Cada entrada de la tabla de páginas contiene el número de marco de la página correspondiente en la memoria principal. Puesto que sólo algunas de las páginas de un proceso pueden estar en la memoria principal, se necesita un bit en cada entrada de la tabla para indicar si la página correspondiente está presente en la memoria principal o no. Si el bit indica que la página está en la memoria, la entrada incluye también el número de marco para esa página.

Estados de una página


Las páginas de un proceso tienen distintos estados, los estados son gestionados por la máquina de estados:

  • Disponible para ejecutar
  • Listo para ejecutar
  • En ejecución
  • Bloqueado y pronto para enviar a Listo para ejecutar
  • No está en ejecución

Tabla de paginación


En cada entrada de la tabla de paginación existe un bit de presencia, que está activado cuando la página se encuentra en memoria principal. Bit de modificado, advierte que la página ha sido Modificada desde que fue traída del disco, y por lo tanto deberá guardarse si es elegida para abandonar la memoria principal. Bit de accedido recientemente, usado en el algoritmo de reemplazo de páginas llamado Menos Usado Recientemente (LRU, least recently used). También hay otros bits indicando los permisos que tiene el proceso sobre la página (leer, escribir, ejecutar).

Las computadoras con poca memoria tienen el problema que marcan el bit LRU de todas las páginas en memoria RAM, es decir todas las páginas que están en memoria son usadas, en caso de tener que traer nuevas páginas desde el disco fijo no cabrán en la memoria RAM y el sistema operativo tendrá que desalojar de la memoria RAM página que son usadas. Se produce un ciclo vicioso de cargar y desalojar páginas de la memoria RAM con mucha frecuencia. Cada vez que el sistema operativo no encuentra una página en memoria RAM se produce un error de página.

Esquema de memoria física y lógica.


El método básico para implementar paginación consiste en dividir la memoria física en bloques de tamaño fijo llamados marcos y dividir la memoria lógica de marcos en bloques del mismo tamaño llamados páginas Cuando un proceso se va a ejecutar, sus páginas son cargadas en cualquier marco de la memoria de almacenamiento secundario. Un proceso es dividido en páginas y las páginas pueden ocupar marcos no contiguas. En caso que un proceso muy grande ocupara más de un marco los marcos pueden ser ubicados en segmentos de memora.

Hardware de paginación entre la CPU y la memoria RAM


El tamaño de página es definido por hardware. El tamaño de una página es típicamente una potencia de 2, variando entre 16B y 16 MB por página, dependiendo de la arquitectura del computador.



Esquema hardware de paginación con el CPU


Cualquier dirección generada por la CPU es divida en dos partes: un número de página (n) y un offset de página (d). El número de página es usado como índice en una tabla de página. La tabla de página contiene las direcciones base de cada página en la memoria física. Esta dirección base es combinada con el offset de página para definir la dirección de memoria física que es enviada a la CPU.

Página n




d (offset)





xx:xx
xx:x1…
xx:xd
xx:xf


El CPU tiene un reducido sistema de datos referente a un segmento o marco, el CPU tiene un número lógico de de página, n, y un número de desplazamiento, d, dentro de la página n.

Es necesario gestionar la traducción de los valores lógicos n y d a los valores físicos de una dirección física de memoria RAM, recordar que la memoria RAM se ha dividido en segmentos y marcos.

Tabla de página de memoria virtual


La tabla de página es una estructura de datos basada en los estados de unos bits, dichos bits marcan los estados de las páginas en el sistema de memoria virtual, el sistema operativo almacenar la relación entre una dirección virtual y las direcciones físicas.

Formas de paginación:

  • Paginar entre la memoria RAM física y el CPU
  • Paginar entre la memoria RAM física y la memoria RAM virtual en el disco fijo

La paginación entra la memoria RAM física y el CPU es muy rápida y depende de la calidad de los componentes hardware. Los CPU tienen memoria cache para guardar páginas, se producen fallos de páginas en la memoria cache del CPU si el CPU constantemente tiene que transferir páginas de la memoria cache a la RAM y de la RAM a la memoria cache del CPU.

La paginación entre la memoria RAM física y la memoria RAM virtual es muy lenta y depende de la eficiencia del disco fijo. Una computadora con poca memoria RAM física puede tener el problema de transferir páginas entre la memoria RAM física y la memoria RAN virtual constantemente, produciendo una degradación general del sistema.



Ejemplo de errores de paginación en la RAM física y virtual


En el siguiente ejemplo vemos una computadora con 1MB de memoria RAM y 1.3MB de memoria virtual y con graves problemas de paginación entre la memoria física RAM y la memoria virtual del disco fijo.

Intercambio, SWAPPING, de páginas entre la memoria RAM y la memoria Virtual


Si hay demasiados intercambios de páginas entra la RAM física y la RAM virtual se producen segmentación o fragmentación de la memoria RAM física. Los sistemas operativos tienen que trabajar demasiado desfragmentando la memoria RAM física. El objetivo de los sistemas operativos es mantener las páginas contiguas y no producir fragmentación de páginas por toda la memoria RAM física.

Degradación del sistema


  • Demasiado acceso al disco fijo, los disco fijos son dispositivos de entrada y salida muy lerdos
  • Fragmentación de memoria RAM, los sistemas operativos tienen que trabajar para desfragmentar la memoria RAM física
  • Fragmentación de memoria RAM virtual, los sistemas operativos tienen que trabajar para desfragmentar la memoria RAN virtual en el disco fijo
  • Tarea de desfragmentación del archivo de memoria virtual
  • Tarea de desfragmentación del direccionamiento de páginas virtuales en el archivo de memoria virtual

La única solución es comprar más memoria RAM física si un sistema es afectado severamente por la degradación de paginación de memoria RAM física y virtual