Статические методы и методы экземпляра в памяти - PullRequest
1 голос
/ 05 февраля 2010

Как эти различные типы методов обрабатываются в памяти.

Я нашел два разных объяснения этому:

  1. Статические методы находятся в памяти только один раз, тогда как методы экземпляра находятся в памяти несколько раз, по одному для каждого экземпляра, чтобы правильно обрабатывать ссылки на переменные-члены в каждом экземпляре.

  2. Все методы находятся в памяти только один раз, а методы экземпляра получают только экземпляр объекта в качестве параметра.

Каким образом используются разные компиляторы?

Ответы [ 3 ]

2 голосов
/ 05 февраля 2010

Короткий ответ, как сказал Йоханнес, почти всегда №2. Оба будут существовать в памяти только в одном месте, но методы экземпляра имеют контекст (который по сути является дополнительным скрытым аргументом), который дает им доступ к экземпляру.

Но: в некоторых языках / средах функция, которая выглядит (для наивного чтения исходного кода), выглядит как одна функция несколько раз. Хороший пример этого - JavaScript: объект функции закрывается за областью, в которой он определен, поэтому, если имеется несколько областей (например, функция, вызываемая более одного раза), в результате получается несколько различных объектов функции. (Интерпретаторы / JIT-ы могут оптимизировать, дублируется ли код , но концептуально это так, и ссылки на функции отличаются.)

Вот пример в JavaScript:

function foo() {

    alert("hi there");
}

function buildBar(x) {

    function bar() {
        alert(x);
    }

    return bar;
}

var f1, f2;

f1 = foo;
f2 = foo;
f1();
// alerts "hi there"
f2();
// alerts "hi there"
alert("f1 === f2 ? " + (f1 === f2));
// alerts "true", there is only one `foo`

var b1, b2;

b1 = buildBar("one");
b2 = buildBar("two");
b1();
// alerts "one"
b2();
// alerts "two"
alert("b1 === b2 ? " + (b1 === b2));
// alerts "false", there are two `bar`s

Это становится уместным в некоторых реализациях «частных» данных экземпляра в JavaScript, где люди определяют методы экземпляра в конструкторе (подобно тому, как buildBar определяет bar), поэтому они имеют доступ к закрытым переменным, объявленным в конструкторе. Это дает желаемый эффект (частные данные экземпляра), но влияет несколько экземпляров функции - по одному для каждого экземпляра объекта.

1 голос
/ 05 февраля 2010

Оба в памяти только один раз. Единственное отличие состоит в том, что методы экземпляра получают еще один первый аргумент: экземпляр самого класса.

То, что существует существует несколько раз в памяти (по крайней мере, для .NET), является универсальными классами и их соответствующими конкретными применениями. Если вы используете и List<int>, и List<string>, то в итоге вы получите две JIT-копии кода, одну для int, одну для string.

0 голосов
/ 05 февраля 2010

Методы экземпляра могут быть виртуальными. Таким образом, для каждого экземпляра объекта времени выполнения с виртуальными методами среда выполнения поддерживает администрирование ссылок на виртуальные методы. Но методы должны существовать только один раз в памяти (но среда выполнения определяет, сколько раз он загружает метод в память).

Для не виртуальных методов ссылки могут быть определены во время компиляции.

...