10

¿Qué idiomas interpretados idiomas sin puntero (IE: Python, Java, Perl, PHP, Ruby, Javascript, etc.) tienen la gestión de memoria manual? No recuerdo haber oído hablar de uno.Idiomas interpretados con gestión de memoria manual?

¿No es la mayor preocupación sobre los lenguajes interpretados los retrasos no deterministas (o la complejidad del espacio cuando no hay suficiente demora) de la recolección de basura? Entonces, ¿por qué no simplemente escribir algo exactamente como Java, pero te obliga a liberar memoria manualmente?

EDITAR

Lo que quiero decir con la gestión de memoria manual es que el lenguaje tendría referencias a objetos, y se puede eliminar el objeto utilizando una referencia.

Ejemplo:

Object a = new Object(); // a is a reference to the object 
Object b = a; // b is a reference to the same object 
a.method(); // fine 
delete b; // delete the object referenced by b 
a.method(); // null dereference exception 

Entonces, ¿qué advertencias (distintas de las pérdidas de memoria) podría haber en un lenguaje como este ejemplo?

+0

por cierto, ¿qué quiere decir con "interpretado" aquí? java es tan "interpretado" como Python, PHP o Javascript en estos días de bytecode. ¿Tal vez sería más preciso mencionar los lenguajes "tipados dinámicamente"? – jsbueno

+0

Cualquier cosa ejecutada por un intérprete, ya sea una especie de forma intermedia o bytecode simple. Particularmente cualquier cosa como php/java/perl/python/ruby ​​que no te dejará basura en tu espacio de direcciones. –

+1

C# no es puntero. –

Respuesta

1

El motivo son las referencias circulares, las excepciones de punteros nulos y las referencias múltiples. Un ejemplo sencillo:

var a = new Object(); 
var b = a; 
a = null;//or delete a or free a or whatever; 
print(b);//what now? is b null? or is b still new Object()? 

Si, en el ejemplo anterior, b es ahora nula, usted termina con algunos problemas importantes cuando la redefinición de las variables. Por ejemplo, en lugar de establecer a en nulo, ¿qué ocurre si lo configura en c? ¿b también sería c?

Puede leer sobre otros problemas, como circular references, on wikipedia.

+0

El problema de referencia circular puede resolverse con la gestión de memoria basada en regiones. Los primeros enfoques manuales fueron arenas y administración de memoria basada en pila, como Forth's FORGET. –

+0

Sí, las referencias nulas habrían estado bien, sin embargo, no pensé en el aliasing de referencia, lo que complica las cosas. –

0

Interpretado no implica necesariamente basura recolectada. Perl, Tcl, Python, etc. Creo que todos usan el recuento de referencias simple, por lo que la recuperación de la memoria es determinista, aunque no del todo transparente (¿alguna vez probado strace en un programa Perl?).

+0

El recuento de referencias es un tipo de recolección de basura, que a menudo se utiliza a pesar de sus fallas porque es fácil de implementar y no depende de la plataforma. –

+0

Sí, pero esto es solo terminología. Quise decir el ref-recuento en línea versus GC-en-el-fondo como en Java/C#. –

+0

Sí, sé que Python hace referencia al recuento. Me refiero a la eliminación explícita de objetos, de modo que hacer dos referencias a ellos y eliminarlos a través de una referencia arrojaría una excepción al intentar acceder al objeto a través de cualquiera de las referencias. –

2

En algunos lenguajes interpretados de alto rendimiento como Lua, puede manejar manualmente la recolección de basura. Ver lua_gc.

4

Forth tiene regiones de memoria apiladas que se pueden liberar con FORGET.

2

Hay algunos intérpretes de C/C++ disponibles, por ejemplo, this one.

No lo probé por mi cuenta, pero creo que como afirma ser compatible con C/C++ compilado, necesita tener una administración de memoria "manual".

0

API de Python oficialmente permite que se gire la recolección de basura en diferido en o fuera - verifique la documentación en el módulo "GC" de la biblioteca estándar:

http://docs.python.org/library/gc.html

Pero eso no es lo que hace que sea lenta cuando se compara con los lenguajes estáticos, la naturaleza dinámica de los datos es la red responsable de las diferencias de velocidad.

1

Así responder a esta parte de la pregunta:

no es la principal preocupación los lenguajes interpretados retrasos no deterministas (o espacio complejidad cuando no hay suficiente retraso) de la basura ¿colección? Entonces, ¿por qué no solo escribe algo exactamente como Java, sino que le obliga a liberar memoria manualmente?

Esto podría ser una preocupación para algunos sistemas. No es tanto un problema para otros sistemas. El software que se ejecuta con recolección de basura puede asignar memoria más rápido que los sistemas que solo llaman malloc. Por supuesto, terminas pagando el tiempo más tarde en la hora del GC.

Tome un sistema basado en la web, por ejemplo. Puede asignar toda la memoria durante el manejo de una solicitud, y el GC puede recopilarse después. Puede que no termine funcionando así, pero entiendes la idea.

Existen muchas estrategias diferentes para la recolección de basura. Qué estrategia es mejor para el sistema dependerá de los requisitos. Pero incluso si requiere un determinismo absoluto, puede usar algo como: Realtime Java

3

¿Qué idiomas interpretados tienen la gestión de memoria manual? No recuerdo haber oído hablar de uno.

No existe un lenguaje interpretado. Un idioma no se compila ni interpreta. Un lenguaje solo es. Un lenguaje es un conjunto de reglas matemáticas abstractas. Interpretación o compilación son rasgos de un lenguaje implementación, tienen nada que ver con el idioma. Cada idioma puede ser implementado por un compilador o un intérprete; las implementaciones de lenguaje de alto rendimiento más modernas realmente usan ambos y cambian entre ellos dependiendo de cuál es más rápido en un contexto particular.

¿Es C un lenguaje compilado? Hay C intérpretes por ahí. ¿Python es un lenguaje interpretado? Las 8 implementaciones actuales de Python usan un compilador.

Por lo tanto, desde cada idioma puede tener una implementación interpretada, C y C++ son ejemplos de lenguajes interpretados con gestión de memoria manual. (Y esto no es solo una competencia teórica, hay son intérpretes de C y C++ en la actualidad. El sistema operativo en tiempo real de VxWorks incluso contiene uno en el kernel, y la NASA alguna vez usó este intérprete para arreglar un buggy módulo kernel en una nave espacial.)

Otro ejemplo sería la primera versión de Lisp de 1958: tenía administración de memoria manual (basada en el conteo de referencias), pero fue reemplazada solo un par de meses después con una versión con gestión de memoria automática, que ha utilizado desde entonces. Aunque de nuevo, cualquier lenguaje se puede implementar con un compilador o un intérprete, por lo que no sé si esa versión tenía una implementación interpretada o compilada. (De hecho, no estoy seguro de si se implementó en todo.)

Si se relaja con su criterio un poco y darse cuenta de que la gestión de memoria es sólo un caso especial de la dirección general de recursos, a continuación, usted encontrará que más o menos todos idiomas, si desea llamar compilado o interpretado o algo completamente diferente, tiene algún tipo de gestión de recursos manual para al menos algún tipo de recurso (manejadores de archivos, conexiones de bases de datos, conexiones de red, cachés, ...).

+0

Creo que interpretó que solo quería decir scripting, como Python, Perl, etc ... tiene razón, pero este es el lugar equivocado para mostrar esta discusión = P. – Claudiu

+0

De hecho, tiene usted razón, pero esto no tiene nada que ver realmente con lo que quise decir en mi pregunta. Trataré de ser más específico de lo que quise decir con un lenguaje interpretado: "lenguajes seguros para la memoria (no necesariamente" script-ish ") que no son tan cercanos al metal como C/C++ que no te dejan trash tu dirección space a menos que _realmente_ desee; lenguajes que son comúnmente compilados y/o interpretados por JIT (y/o incluso compilados en código byte antes de ese proceso (y o compilados por adelantado)). –

18

Las premisas detrás de la pregunta son un poco fiable:

  • El modelo de memoria es una propiedad de la lengua, no su implementación.

  • Ser interpretado es una propiedad de una implementación , no es un idioma.

Ejemplos:

  • El lenguaje de programación Scheme tiene la gestión de memoria automática, y tiene muchas decenas de implementaciones interpretados, pero también algunas compiladores de código nativo finas incluyendo hurto, Gambito, y PLT Scheme (que incluye ambos un intérprete y un compilador JIT haciendo transiciones perfectas).

  • El lenguaje de programación Haskell tiene memoria automática managemend; las dos implementaciones más famosas son el intérprete HUGS y el compilador GHC. Hay varias otras implementaciones honorables divididas de forma equitativa entre compilar a código nativo (yhc) e interpretación (Helium).

  • El lenguaje de programación C tiene administración de memoria manual, y mientras el mundo está lleno de compiladores de C, aquellos de nosotros lo suficientemente mayores como para recordar la gloriosa década de 1980 recordaremos Sabre-C o C-terp, dos intérpretes C muy útiles MS-DOS.

Sin embargo, hay una observación veraz detrás de la pregunta: idiomas con la gestión de memoria manual están típicamente compiladas. ¿Por qué?

  • Manual de gestión de memoria es una función heredada, a menudo utilizado para ser compatible con el código heredado. Los lenguajes heredados suelen ser lo suficientemente maduros para tener compiladores de código nativo.

  • Muchos idiomas nuevos se definen mediante una implementación. Es más fácil construir un intérprete que construir un compilador. Es más fácil implementar una gestión de memoria automática simple en un intérprete que implementar una gestión de memoria automática de alto rendimiento en un compilador de código nativo. Entonces, si el lenguaje obtiene su definición desde su primera implementación, la gestión automática de la memoria se correlaciona con la interpretación, porque en la configuración interpretada, la implementación es más fácil.

  • La administración manual de la memoria también se usa (y algunas veces incluso de manera justificada) para mejorar el rendimiento. Los excelentes estudios experimentales de Ben Zorn de la década de 1990 muestran que la gestión automática de la memoria es tan rápida o más rápida que la gestión manual de la memoria, pero requiere aproximadamente el doble de memoria.De modo que la administración manual de la memoria se usa a menudo en dispositivos muy pequeños, donde la memoria es escasa, y en centros de datos muy grandes, donde duplicar la memoria es costoso. (A veces también lo usan personas que no saben mucho sobre administración de memoria, pero que han escuchado que la recolección de basura es lenta. Tenían razón en 1980). Y cuando hay una preocupación por el rendimiento, normalmente se encuentra un compilador de código nativo que un intérprete

    Algunas de las excepciones realmente interesantes también provienen de este principio. Por ejemplo, tanto FORTH como las primeras implementaciones de PostScript se diseñaron para ejecutarse en pequeños dispositivos integrados (telescopios e impresoras) donde los recursos de memoria eran escasos pero el tiempo de cómputo no era un factor. Ambos lenguajes se implementaron primero utilizando códigos de byte que eran más compactos que el código nativo, y ambos presentaban administración de memoria manual. Entonces: intérpretes con gestión de memoria manual. (Más tarde versiones de PostScript añadido una opción para la recolección de basura.)

En resumen:

  • automática frente a la gestión de memoria manual es el lenguaje .

  • Compilado vs interpretado es la aplicación .

  • En principio las dos opciones pueden ser y están hechos de forma ortogonal, pero por razones de ingeniería pragmáticos gestión de memoria automática se correlaciona frecuentemente con la interpretación.

no es la mayor preocupación por los lenguajes interpretados los retrasos no deterministas (o complejidad espacio cuando no hay suficiente retardo) de la recolección de basura?

yo no era consciente de que no era una gran preocupación acerca de las implementaciones de lenguajes de programación interpretados. En orden alfabético, Lua, Perl, PostScript, Python y Ruby tienen mucho éxito, e Icon, Scheme y Squeak Smalltalk tienen un éxito moderado. La única área en la que las demoras impredecibles son motivo de preocupación es en la informática dura en tiempo real, como el sistema ABS que controla los frenos de su automóvil (si conduce un automóvil lo suficientemente elegante).


Nota añadida después de la pregunta fue editado: ¿Ha cambiado "interpretado" a "triple libre". Pero dices en un comentario que quieres preguntar sobre los idiomas con new y delete. Cualquier idioma con new y delete tiene punteros: por definición, lo que new devuelve es un puntero. (En algunos idiomas, también puede haber otras fuentes de punteros). Por lo tanto, creo que lo que quiere decir es "idiomas sin aritmética de puntero y sin un operador de dirección de usuario".

+0

Gestión manual de la memoria como en los operadores 'new' y' delete'. Intentar desreferenciar un objeto 'delete'd causará una excepción o algún tipo de otro error en lugar de un comportamiento indefinido. Básicamente lo mismo que Java pero con un operador de eliminación, por ejemplo. Sin embargo, tiene un buen punto acerca de que la administración manual de la memoria es un legado. –

Cuestiones relacionadas